كيفية حساب الكلمات في MySQL / استبدال التعبير العادي؟

StackOverflow https://stackoverflow.com/questions/1755408

سؤال

كيف يمكنني ، في استعلام MySQL ، نفس السلوك مثل وظيفة regex.replace (على سبيل المثال في .NET/C#)؟

أحتاج إلى ذلك لأنه ، مثل العديد من الناس ، أود حساب عدد الكلمات في حقل. ومع ذلك ، لست راضيا عن الإجابة التالية (معطى عدة مرات على هذا الموقع):

SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', '') +1 FROM table

لأنه لا يعطي نتائج جيدة عندما يكون هناك المزيد من هذه المساحة بين كلمتين.

بالمناسبة ، أعتقد أن وظيفة regex.replace قد تكون مثيرة للاهتمام ، لذا فإن جميع الأفكار الجيدة مرحب بها!

هل كانت مفيدة؟

المحلول

هناك regexp_replace متاح ك وظائف MySQL المعرفة من قبل المستخدم.

حساب الكلمات: إذا كان يمكنك التحكم في البيانات التي تدخل في قاعدة البيانات ، فيمكنك إزالة مساحة البيضاء المزدوجة قبل الإدراج. أيضًا إذا كان عليك الوصول إلى عدد الكلمات في كثير من الأحيان ، يمكنك حسابه مرة واحدة في الكود وتخزين العدد في قاعدة البيانات.

نصائح أخرى

تحديث: أضاف الآن إجابة منفصلة لـ MySQL 8.0+, والتي يجب استخدامها في التفضيل. (احتفظت بهذه الإجابة في حالة التقييد على استخدام إصدار سابق.)

تقريبا مكررة من هذا السؤال ولكن هذه الإجابة ستتناول حالة استخدام الكلمات بناءً على الإصدار المتقدم من بدائل التعبير العادية المخصصة من منشور المدونة هذا.

العرض التوضيحي

REXTESTER ONLINE DEMO

بالنسبة لنص العينة ، يعطي هذا عدد 61 - مثل جميع عدادات الكلمات عبر الإنترنت التي جربتها (على سبيل المثال https://wordcounter.net/).

SQL (باستثناء رمز الوظيفة للإيجاز):

SELECT txt,
       -- Count the number of gaps between words
       CHAR_LENGTH(txt) -
       CHAR_LENGTH(reg_replace(txt,
                               '[[:space:]]+', -- Look for a chunk of whitespace
                               '^.', -- Replace the first character from the chunk
                               '',   -- Replace with nothing (i.e. remove the character)
                               TRUE, -- Greedy matching
                               1,  -- Minimum match length
                               0,  -- No maximum match length
                               1,  -- Minimum sub-match length
                               0   -- No maximum sub-match length
                               ))
       + 1 -- The word count is 1 more than the number of gaps between words
       - IF (txt REGEXP '^[[:space:]]', 1, 0) -- Exclude whitespace at the start from count
       - IF (txt REGEXP '[[:space:]]$', 1, 0) -- Exclude whitespace at the end from count
       AS `word count`
FROM tbl;

الجواب هو لا ، لا يمكنك الحصول على نفس السلوك في MySQL.

لكني أوصيك بالخروج هذا في وقت سابق سؤال حول الموضوع الذي يرتبط بـ UDF الذي يُفترض أنه يمكّن بعض هذه الوظائف.

MySQL 8.0 يوفر الآن لائق regexp_replace الوظيفة ، مما يجعل هذا أكثر بساطة:

SQL

SELECT -- Count the number of gaps between words
       CHAR_LENGTH(txt) -
           CHAR_LENGTH(REGEXP_REPLACE(
               txt,
               '[[:space:]]([[:space:]]*)', -- A chunk of one or more whitespace characters
               '$1')) -- Discard the first whitespace character and retain the rest
           + 1 -- The word count is 1 more than the number of gaps between words
           - IF (txt REGEXP '^[[:space:]]', 1, 0) -- Exclude whitespace at the start from count
           - IF (txt REGEXP '[[:space:]]$', 1, 0) -- Exclude whitespace at the end from count
           AS `Word count`
FROM tbl;

العرض التوضيحي

DB-FIDDLE عبر الإنترنت

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top