MySQL में नियमित अभिव्यक्ति कैसे करें?


515

मेरे पास ~ 500k पंक्तियों वाली एक तालिका है; varchar (255) UTF8 कॉलम filenameमें एक फ़ाइल नाम है;

मैं विभिन्न अजीब चरित्रों को फिल्म के नाम से हटाने की कोशिश कर रहा हूं - सोचा कि मैं एक चरित्र वर्ग का उपयोग करूंगा: [^a-zA-Z0-9()_ .\-]

अब, MySQL में एक फ़ंक्शन है जो आपको एक नियमित अभिव्यक्ति के माध्यम से बदल देता है ? मैं REPLACE () फ़ंक्शन के लिए समान कार्यक्षमता की तलाश कर रहा हूं - सरलीकृत उदाहरण इस प्रकार है:

SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-'); 

Output: "-tackover-low"

मैं के बारे में पता regexp / RLIKE , लेकिन उन केवल जाँच करता है, तो मिलान हो जाता है, नहीं क्या मुकाबला नहीं है।

(मैं एक PHP स्क्रिप्ट से एक " " कर सकता थाSELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]' , एक preg_replaceऔर फिर " UPDATE foo ... WHERE pkey_id=..." कर सकता हूं , लेकिन यह एक अंतिम-रिज़ॉर्ट की तरह दिखता है और बहुत अच्छी तरह से दिखाई देता है)


8
यह 2007 के बाद से एक फीचर अनुरोध है: Bugs.mysql.com/bug.php?id=27389 । यदि आप वास्तव में यह सुविधा चाहते हैं, तो लॉग इन करें और "मुझे प्रभावित करता है" बटन पर क्लिक करें। उम्मीद है कि इसे पर्याप्त वोट मिलेंगे।
TMS

4
@ टॉमास: मैंने वह किया है ... 2009 में, जब मैं इसके लिए चारों ओर देख रहा था। चूंकि इस पर शून्य प्रगति हुई है - जाहिर है यह इतनी महत्वपूर्ण विशेषता नहीं है। (btw Postgres has it: stackoverflow.com/questions/11722995/… )
पिस्कॉर ने बिल्डिंग

1
संबंधित, सरल, इस सवाल का संस्करण: stackoverflow.com/questions/6942973/…
Kzqai

2
मैंने बनाया regexp_split(फ़ंक्शन + प्रक्रिया) और regexp_replace, जिसे REGEXPऑपरेटर के साथ लागू किया गया है। सरल लुकअप के लिए, यह ट्रिक करेगा। आप इसे यहाँ पा सकते हैं - तो, ​​यह MySQL संग्रहीत कोड के साथ तरीका है, कोई UDF नहीं। यदि आपको कुछ बग मिलेंगे, जो ज्ञात सीमाओं से ढके नहीं हैं - समस्या को खोलने के लिए स्वतंत्र महसूस करें।
अल्मा दो

1
इस लाइब्रेरी को अन्य SO थ्रेड से मिला: github.com/mysqludf/lib_mysqludf_preg पूरी तरह से काम करता है।
काइल

जवाबों:


77

MySQL 8.0+ के साथ आप मूल रूप से REGEXP_REPLACEफ़ंक्शन का उपयोग कर सकते हैं ।

12.5.2 नियमित अभिव्यक्तियाँ :

REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])

स्ट्रिंग एक्सप्रैस में होने वाली रिप्लेसमेंट जो रिप्लेसमेंट स्ट्रिंग रिप्लाई के साथ पैटर्न पैट द्वारा निर्दिष्ट रेगुलर एक्सप्रेशन से मेल खाती है , और परिणामस्वरूप स्ट्रिंग को वापस करती है। यदि expr , पैट , या repl है , वापसी मान है ।NULLNULL

और नियमित अभिव्यक्ति समर्थन :

पहले, MySQL ने नियमित अभिव्यक्ति ऑपरेटरों ( REGEXP, RLIKE) का समर्थन करने के लिए हेनरी स्पेंसर नियमित अभिव्यक्ति पुस्तकालय का उपयोग किया ।

यूनिकोड (ICU) के लिए अंतर्राष्ट्रीय अवयवों का उपयोग करके नियमित अभिव्यक्ति समर्थन को फिर से लागू किया गया है, जो पूर्ण यूनिकोड समर्थन प्रदान करता है और यह बहुपयोगी सुरक्षित है। REGEXP_LIKE()समारोह के ढंग से नियमित अभिव्यक्ति मिलान करता है REGEXPऔर RLIKEऑपरेटरों, जो अब है कि समारोह के लिए समानार्थक शब्द हैं। इसके अलावा, REGEXP_INSTR(), REGEXP_REPLACE(), और REGEXP_SUBSTR() कार्यों मैच पदों को खोजने के लिए उपलब्ध हैं और क्रमश: प्रतिस्थापन और निष्कर्षण सबस्ट्रिंग प्रदर्शन,।

SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
-- Output:
-tackover-low

DBFiddle डेमो


146

MySQL 8.0+ :

आप मूल REGEXP_REPLACEफ़ंक्शन का उपयोग कर सकते हैं ।

पुराने संस्करण:

आप mysql-udf-regexp जैसे उपयोगकर्ता-परिभाषित फ़ंक्शन ( UDF ) का उपयोग कर सकते हैं ।


3
REGEXP_REPLACE उपयोगकर्ता परिभाषित फ़ंक्शन के रूप में? होनहार लग रहा है, इस पर गौर करेंगे। धन्यवाद!
पिस्कोर ने

15
दुर्भाग्य से mysql-udf-regexp को मल्टीबाइट पात्रों के लिए समर्थन नहीं लगता है। regexp_replace ('äö'ü', 'ä', '') वास्तविक पाठ के बजाय एक लंबा संख्यात्मक स्ट्रिंग देता है।
lkraav

3
MySQL स्वयं अपने RegEx सुविधाओं के साथ मल्टी-बाइट वर्णों का समर्थन नहीं करता है।
ब्रैड

4
विंडोज यूजर्स: यहां से जुड़ी यूडीएफ लाइब्रेरी में अच्छी विंडोज सपोर्ट नहीं है। मेरे द्वारा बताई गई विंडोज़ इंस्टॉलेशन विधि अच्छी तरह से काम नहीं करती है।
जोनाथन

2
@lkraav आपको lib_mysqludf_preg लाइब्रेरी को नीचे आज़माना चाहिए क्योंकि यह बहुत अच्छा काम करता है। यह वर्बोज़ संस्करण है क्योंकि यह डिफ़ॉल्ट रूप से एक बूँद लौटाता है और मुझे नहीं पता कि आपके पास अपने डिफ़ॉल्ट के रूप में एक मल्टीबैट चारसेट है: कास्ट (TR as char) COLLATE utf8_unicode_ci से (select preg_place ('/ ä /', '') का चयन करें। 'ö güä') आर) टी
गिल्पी

124

इसके बजाय MariaDB का उपयोग करें। इसका एक फंक्शन है

REGEXP_REPLACE(col, regexp, replace)

देखें MariaDB डॉक्स और PCRE नियमित अभिव्यक्ति संवर्द्धन

ध्यान दें कि आप regexp समूहीकरण का उपयोग कर सकते हैं (मैंने पाया कि बहुत उपयोगी है):

SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\\2 - \\1 - \\3')

रिटर्न

over - stack - flow

12
यह मारीदब 10 से है
निक

6
अगली बार मुझे इसकी आवश्यकता है, यहाँ एक पूरे कॉलम को बदलने के लिए सिंटैक्स: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\\1")यह एक बार में एक पूरे कॉलम से -2 एबीसीआईएक्स -2 से निकालता है।
जोसिया

27
एक पूरे मंच को बदलना शायद ही एक यथार्थवादी समाधान है।
डेविड बॉउम

3
@DavidBaucum MariaDB MySQL के लिए एक ड्रॉप-इन प्रतिस्थापन है। तो यह "प्लेटफ़ॉर्म का परिवर्तन" नहीं है, लेकिन एक ही यात्रा के लिए एक अलग एयरलाइन चुनने की तरह
बेनोर्थ


113

यह काम करने के लिए मेरी पाशविक बल विधि सिर्फ:

  1. तालिका डंप करें - mysqldump -u user -p database table > dump.sql
  2. एक दो पैटर्न खोजें और बदलें - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} \;, जाहिर है कि आप फ़ाइल पर भी प्रदर्शन कर सकते हैं।
  3. तालिका आयात करें - mysqlimport -u user -p database table < dump.sql

यदि आप यह सुनिश्चित करना चाहते हैं कि स्ट्रिंग आपके डेटासेट में कहीं और नहीं है, तो सुनिश्चित करें कि वे सभी समान वातावरण में होने के लिए कुछ नियमित अभिव्यक्ति चलाएं। यदि आप गलती से किसी चीज़ को नष्ट कर देते हैं, तो सूचना को गहराई से नष्ट करने से पहले, बैकअप बनाना कठिन नहीं है।


33
ठीक है, वह भी काम करना चाहिए; मैंने एक ऑफ़लाइन प्रतिस्थापन पर विचार नहीं किया। अच्छा-ख़ासा सोच-विचार कर वहाँ से निकले!
पिस्कोर ने

10
मेरे लिए अजीब है कि आप इस तरह लगता है का उपयोग करेंगे लगता है, मैं आदेश को छोटा होता एसईडी मैं के / old_string / new_string / जी '/path/to/dump.sql
speshak

36
बहुत जोखिम भरा है, और बड़े डेटा सेट के साथ या जगह में संदर्भात्मक अखंडता के साथ अव्यावहारिक: डेटा को निकालने के लिए और फिर इसे फिर से डालें आपको अपने डेटाबेस को भी बंद करके व्यवहारिक अखंडता को बंद करना होगा।
राउल लूना

5
अतीत में इस पद्धति का उपयोग करने के बाद, मैं राउल से सहमत हूं, यह बहुत जोखिम भरा है। आपको पूरी तरह से निश्चित होना चाहिए, कि आपका तार आपके डेटासेट में नहीं है।
अंडेमेकर्स

1
@Speshak को जवाब देने में देर हो गई लेकिन मैंने इस तरह से फ़ाइल को एक्सेस करने का कारण चुना क्योंकि मैं ऊपर बताए गए कारणों से मूल रूप से बहुत घबराया हुआ था। जिस समय ऐसा लग रहा था कि "फ़ाइल" भाग को "प्रतिस्थापित" भाग से अलग करने से पहले मुझे इसे सबमिट करने से पहले कोड को पढ़ना आसान हो जाएगा
रयान वार्ड

42

हम इस समस्या का समाधान किए बिना रेगेक्स का उपयोग करते हुए इस क्वेरी को केवल सटीक मिलान स्ट्रिंग की जगह लेते हैं।

update employee set
employee_firstname = 
trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))

उदाहरण:

एम्प्लॉइड कर्मचारी_फर्स्टनाम

1 जय

2 जय अज

3 जय

क्वेरी परिणाम निष्पादित करने के बाद:

एम्प्लॉइड कर्मचारी_फर्स्टनाम

1 एबीसी

2 एबीसी अज

3 एबीसी


@yellowmelon दोहरे उद्धरण चिह्नों के दो जोड़े कौन से हैं?
कोडकॉबॉय

5
वह पहले और बाद के रिक्त स्थान के साथ नियोजन नाम पैडिंग कर रहा है। यह उसे (स्थान) नियोजननाम (स्थान) के लिए खोज-प्रतिस्थापित करने की अनुमति देता है, जो कि नियोजन नाम "जय" को पकड़ने से बचता है यदि इसका एक बड़ा स्ट्रिंग "अज" का हिस्सा है। फिर वह रिक्त स्थान को ट्रिम कर देता है जब किया जाता है।
स्लैम

42

मैंने हाल ही में नियमित अभिव्यक्तियों का उपयोग करके स्ट्रिंग को बदलने के लिए एक MySQL फ़ंक्शन लिखा था। आप निम्न स्थान पर मेरी पोस्ट पा सकते हैं:

http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/

यहाँ फ़ंक्शन कोड है:

DELIMITER $$

CREATE FUNCTION  `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
RETURNS VARCHAR(1000)
DETERMINISTIC
BEGIN 
 DECLARE temp VARCHAR(1000); 
 DECLARE ch VARCHAR(1); 
 DECLARE i INT;
 SET i = 1;
 SET temp = '';
 IF original REGEXP pattern THEN 
  loop_label: LOOP 
   IF i>CHAR_LENGTH(original) THEN
    LEAVE loop_label;  
   END IF;
   SET ch = SUBSTRING(original,i,1);
   IF NOT ch REGEXP pattern THEN
    SET temp = CONCAT(temp,ch);
   ELSE
    SET temp = CONCAT(temp,replacement);
   END IF;
   SET i=i+1;
  END LOOP;
 ELSE
  SET temp = original;
 END IF;
 RETURN temp;
END$$

DELIMITER ;

उदाहरण निष्पादन:

mysql> select regex_replace('[^a-zA-Z0-9\-]','','2my test3_text-to. check \\ my- sql (regular) ,expressions ._,');

25
मैं सिर्फ उपरोक्त बिंदु को सुदृढ़ करूंगा: यह फ़ंक्शन एकल-वर्ण अभिव्यक्ति से मेल खाने वाले वर्णों को बदलता है । यह ऊपर कहा गया है कि इसका उपयोग "नियमित अभिव्यक्तियों का उपयोग करके तारों को फिर से विभाजित करने के लिए" किया जाता है, और यह थोड़ा भ्रामक हो सकता है। यह अपना काम करता है, लेकिन यह वह काम नहीं है जिसके लिए कहा जा रहा है। (कोई शिकायत नहीं - यह सिर्फ लोगों को गलत रास्ते से बचाने के लिए है)
जेसन

2
यह वास्तव में एक नग्न लिंक पोस्ट करने के बजाय आपके उत्तर में कोड शामिल करने के लिए अधिक उपयोगी होगा।
फोबिया

2
नाइस - लेकिन दुर्भाग्य से संदर्भों के साथ सौदा नहीं करता है जैसे select regex_replace('.*(abc).*','\1','noabcde')('नाकाबंदी', 'एबीसी' नहीं)।
इज़्ज़ी

@phobie किसी और ने इस जवाब में - लिंक के मरने की स्थिति में एक संदर्भ के रूप में;)
इज़्ज़ी

मैंने ऊपर बताई गई कुछ सीमाओं को संबोधित करने के प्रयास के लिए इस विधि को संशोधित किया है। कृपया इसका उत्तर देखें ।
स्टीव चेम्बर्स

14

मुझे यह बताते हुए खुशी हो रही है कि चूंकि यह प्रश्न पूछा गया था, इसलिए अब इसका संतोषजनक उत्तर है! इस भयानक पैकेज पर एक नज़र डालें:

https://github.com/mysqludf/lib_mysqludf_preg

नमूना SQL:

SELECT PREG_REPLACE('/(.*?)(fox)/' , 'dog' , 'the quick brown fox' ) AS demo;

मुझे इस प्रश्न के लिंक के रूप में इस ब्लॉग पोस्ट से पैकेज मिला ।


13

अद्यतन 2: REGEXP_REPLACE सहित regex फ़ंक्शंस का एक उपयोगी सेट अब MySQL 8.0 में प्रदान किया गया है। जब तक आप पहले वाले संस्करण का उपयोग करने के लिए विवश न हों, यह अनावश्यक रूप से पढ़ता है।


अद्यतन 1: अब इसे एक ब्लॉग पोस्ट में बनाया है: http://stevettt.blogspot.co.uk/2018/02/a-mysql- अनियमित-expression-replace.html


रासिका गोडावटे द्वारा प्रदान किए गए फ़ंक्शन पर निम्नलिखित विस्तार होता है, लेकिन केवल एकल पात्रों के परीक्षण के बजाय सभी आवश्यक पदार्थों के माध्यम से पता चलता है :

-- ------------------------------------------------------------------------------------
-- USAGE
-- ------------------------------------------------------------------------------------
-- SELECT reg_replace(<subject>,
--                    <pattern>,
--                    <replacement>,
--                    <greedy>,
--                    <minMatchLen>,
--                    <maxMatchLen>);
-- where:
-- <subject> is the string to look in for doing the replacements
-- <pattern> is the regular expression to match against
-- <replacement> is the replacement string
-- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
-- <minMatchLen> specifies the minimum match length
-- <maxMatchLen> specifies the maximum match length
-- (minMatchLen and maxMatchLen are used to improve efficiency but are
--  optional and can be set to 0 or NULL if not known/required)
-- Example:
-- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
DROP FUNCTION IF EXISTS reg_replace;
DELIMITER //
CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
  replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
RETURNS VARCHAR(21845) DETERMINISTIC BEGIN 
  DECLARE result, subStr, usePattern VARCHAR(21845); 
  DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
  IF subject REGEXP pattern THEN
    SET result = '';
    -- Sanitize input parameter values
    SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
    SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
                         CHAR_LENGTH(subject), maxMatchLen);
    -- Set the pattern to use to match an entire string rather than part of a string
    SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
    SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
    -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
    IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
      SET startPos = 1, startInc = 1;
    -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
    -- to the min or max match length from the end (depending on "greedy" flag).
    ELSEIF greedy THEN
      SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
    ELSE
      SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
    END IF;
    WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
      AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
      AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
      AND !(RIGHT(pattern, 1) = '$'
            AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
      -- Set start length to maximum if matching greedily or pattern ends with $.
      -- Otherwise set starting length to the minimum match length.
      IF greedy OR RIGHT(pattern, 1) = '$' THEN
        SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
      ELSE
        SET len = minMatchLen, lenInc = 1;
      END IF;
      SET prevStartPos = startPos;
      lenLoop: WHILE len >= 1 AND len <= maxMatchLen
                 AND startPos + len - 1 <= CHAR_LENGTH(subject)
                 AND !(RIGHT(pattern, 1) = '$' 
                       AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
        SET subStr = SUBSTRING(subject, startPos, len);
        IF subStr REGEXP usePattern THEN
          SET result = IF(startInc = 1,
                          CONCAT(result, replacement), CONCAT(replacement, result));
          SET startPos = startPos + startInc * len;
          LEAVE lenLoop;
        END IF;
        SET len = len + lenInc;
      END WHILE;
      IF (startPos = prevStartPos) THEN
        SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
                        CONCAT(SUBSTRING(subject, startPos, 1), result));
        SET startPos = startPos + startInc;
      END IF;
    END WHILE;
    IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
      SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
    ELSEIF startInc = -1 AND startPos >= 1 THEN
      SET result = CONCAT(LEFT(subject, startPos), result);
    END IF;
  ELSE
    SET result = subject;
  END IF;
  RETURN result;
END//
DELIMITER ;

डेमो

Rextester डेमो

सीमाएं

  1. यह विधि निश्चित रूप से समय लेने वाली है जब विषय स्ट्रिंग बड़ी है। अद्यतन: अब बेहतर दक्षता के लिए न्यूनतम और अधिकतम मिलान लंबाई पैरामीटर जोड़ा है जब ये ज्ञात (शून्य = अज्ञात / असीमित) हैं।
  2. यह कैप्चरिंग समूहों को बदलने के लिए बैकरेफरेंस (जैसे , आदि) के प्रतिस्थापन की अनुमति नहीं देगा । यदि इस कार्यक्षमता की आवश्यकता है, तो कृपया इस उत्तर को देखें\1\2 जो कि एक पाया हुआ मैच के भीतर (पाया गया जटिलता की कीमत पर) एक माध्यमिक खोज की अनुमति देने के लिए फ़ंक्शन को अपडेट करके वर्कअराउंड प्रदान करने का प्रयास करता है।
  3. यदि ^और / या $पैटर्न में उपयोग किया जाता है, तो उन्हें क्रमशः बहुत शुरुआत और बहुत अंत में होना चाहिए - जैसे पैटर्न (^start|end$)समर्थित नहीं हैं।
  4. एक "लालची" ध्वज है यह निर्दिष्ट करने के लिए कि क्या समग्र मिलान लालची या गैर-लालची होना चाहिए। एक नियमित अभिव्यक्ति (जैसे a.*?b.*) के भीतर लालची और आलसी के मेल का समर्थन नहीं किया जाता है।

उपयोग के उदाहरण

फ़ंक्शन का उपयोग निम्नलिखित StackOverflow सवालों के जवाब देने के लिए किया गया है:


7

आप इसे कर सकते हैं ... लेकिन यह बहुत बुद्धिमान नहीं है ... यह उतना ही साहसी है जितना कि मैं कोशिश करूँगा ... जहाँ तक कि पूर्ण RegEx पर्ल या इस तरह का उपयोग करके आपके बहुत बेहतर समर्थन करता है।

UPDATE db.tbl
SET column = 
CASE 
WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]' 
THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
END 
WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'

1
नहीं, यह काम नहीं करेगा। कल्पना करें कि आपके कॉलम में 'asdfWORD_TO_REPLACE WORD_TO_REPLACE' है। आपकी विधि 'asdfREPLACEMENT REPLACEMENT "के परिणामस्वरूप होगी, जहाँ सही उत्तर" asdfWORD_TO_REPLACE REPLACEMENT "होगा।
रयान

1
@ रेयान ... यही कारण है कि मैंने कहा कि यह बहुत बुद्धिमान नहीं था ... उपयोग के मामले में आप इसे सबसे निश्चित रूप से विफल कर देंगे। संक्षेप में 'रेगेक्स जैसी' संरचना का उपयोग करना एक बुरा विचार है। इससे भी बदतर ... अगर आप उस खंड को छोड़ देते हैं जहां आपके सभी मूल्य NULL होंगे ...
एडी बी

1
वास्तव में रयान इस मामले में आप गलत हैं क्योंकि मार्कर केवल शून्य-लंबाई शब्द 'सीमा' के लिए मैच पाएंगे, इसलिए शब्द से पहले और बाद में सीमाओं के साथ केवल शब्द मेल खाते हैं ... यह अभी भी एक बुरा विचार है ...
एडी बी

6

हम निम्न स्थिति में सेलेक्ट क्वेरी में IF कंडीशन का उपयोग कर सकते हैं:

मान लीजिए कि "एबीसी", "एबीसी 1", "एबीसी 2", "एबीसी 3", ..., के साथ किसी भी चीज के लिए, हम "एबीसी" के साथ प्रतिस्थापित करना चाहते हैं, तो SELEX क्वेरी में REGEXP और IF () स्थिति का उपयोग करके, हम इसे प्राप्त कर सकते हैं ।

वाक्य - विन्यास:

SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
FROM table1 
WHERE column_name LIKE 'ABC%';

उदाहरण:

SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');

नमस्कार, सुझाव के लिए धन्यवाद। मैं कुछ इसी तरह की कोशिश कर रहा हूं, लेकिन मेरे डेटा सेट पर प्रदर्शन असंतोषजनक रहा है। छोटे सेट के लिए, यह व्यवहार्य हो सकता है।
पिस्कोर ने इमारत

3

नीचे वाला मूल रूप से बाईं ओर से पहला मैच पाता है और फिर इसके सभी घटनाओं को बदल देता है (परीक्षण किया जाता है) )।

उपयोग:

SELECT REGEX_REPLACE('dis ambiguity', 'dis[[:space:]]*ambiguity', 'disambiguity');

कार्यान्वयन:

DELIMITER $$
CREATE FUNCTION REGEX_REPLACE(
  var_original VARCHAR(1000),
  var_pattern VARCHAR(1000),
  var_replacement VARCHAR(1000)
  ) RETURNS
    VARCHAR(1000)
  COMMENT 'Based on https://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/'
BEGIN
  DECLARE var_replaced VARCHAR(1000) DEFAULT var_original;
  DECLARE var_leftmost_match VARCHAR(1000) DEFAULT
    REGEX_CAPTURE_LEFTMOST(var_original, var_pattern);
    WHILE var_leftmost_match IS NOT NULL DO
      IF var_replacement <> var_leftmost_match THEN
        SET var_replaced = REPLACE(var_replaced, var_leftmost_match, var_replacement);
        SET var_leftmost_match = REGEX_CAPTURE_LEFTMOST(var_replaced, var_pattern);
        ELSE
          SET var_leftmost_match = NULL;
        END IF;
      END WHILE;
  RETURN var_replaced;
END $$
DELIMITER ;

DELIMITER $$
CREATE FUNCTION REGEX_CAPTURE_LEFTMOST(
  var_original VARCHAR(1000),
  var_pattern VARCHAR(1000)
  ) RETURNS
    VARCHAR(1000)
  COMMENT '
  Captures the leftmost substring that matches the [var_pattern]
  IN [var_original], OR NULL if no match.
  '
BEGIN
  DECLARE var_temp_l VARCHAR(1000);
  DECLARE var_temp_r VARCHAR(1000);
  DECLARE var_left_trim_index INT;
  DECLARE var_right_trim_index INT;
  SET var_left_trim_index = 1;
  SET var_right_trim_index = 1;
  SET var_temp_l = '';
  SET var_temp_r = '';
  WHILE (CHAR_LENGTH(var_original) >= var_left_trim_index) DO
    SET var_temp_l = LEFT(var_original, var_left_trim_index);
    IF var_temp_l REGEXP var_pattern THEN
      WHILE (CHAR_LENGTH(var_temp_l) >= var_right_trim_index) DO
        SET var_temp_r = RIGHT(var_temp_l, var_right_trim_index);
        IF var_temp_r REGEXP var_pattern THEN
          RETURN var_temp_r;
          END IF;
        SET var_right_trim_index = var_right_trim_index + 1;
        END WHILE;
      END IF;
    SET var_left_trim_index = var_left_trim_index + 1;
    END WHILE;
  RETURN NULL;
END $$
DELIMITER ;

3

मुझे लगता है कि इसे हासिल करने का एक आसान तरीका है और यह मेरे लिए ठीक काम कर रहा है।

REGEX का उपयोग करके पंक्तियों का चयन करें

SELECT * FROM `table_name` WHERE `column_name_to_find` REGEXP 'string-to-find'

REGEX का उपयोग करके पंक्तियों को अद्यतन करने के लिए

UPDATE `table_name` SET column_name_to_find=REGEXP_REPLACE(column_name_to_find, 'string-to-find', 'string-to-replace') WHERE column_name_to_find REGEXP 'string-to-find'

REGEXP संदर्भ: https://www.geeksforgeeks.org/mysql- अनियमित-expressions-regexp /


धन्यवाद :) संस्करण 8 के बाद से यह आसानी से करना संभव है
पिस्कवर ने भवन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.