মাইএসকিউএল-এ নিয়মিত প্রকাশটি কীভাবে প্রতিস্থাপন করবেন?


515

আমার কাছে 500 টাকার সারি সহ একটি টেবিল রয়েছে; ভারচার (255) ইউটিএফ 8 কলামে filenameএকটি ফাইলের নাম রয়েছে;

আমি ফাইলের নাম থেকে বিভিন্ন অদ্ভুত চরিত্রগুলি ছাঁটাই করার চেষ্টা করছি - ভেবেছিলাম আমি একটি অক্ষর শ্রেণি ব্যবহার করব: [^a-zA-Z0-9()_ .\-]

এখন, মাইএসকিউএলে এমন কোনও ফাংশন রয়েছে যা আপনাকে নিয়মিত প্রকাশের মাধ্যমে প্রতিস্থাপন করতে দেয় ? আমি রিপ্লেস () ফাংশনটির অনুরূপ কার্যকারিতা খুঁজছি - সরল উদাহরণটি নিম্নলিখিত:

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

Output: "stackoverflow"

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

Output: "-tackover-low"

আমি রেগেক্স / রিলাইক সম্পর্কে জানি , তবে তারাই কেবল ম্যাচটি কিনা তা পরীক্ষা করে দেখায় , ম্যাচটি কী তা নয় ।

(আমি পিএইচপি স্ক্রিপ্ট থেকে একটি " " করতে পেরেছিলাম, একটি করতে পারি এবং পরে " " করতে পারি, তবে এটি সর্বশেষ-রিসর্টটি ধীর এবং কুশ্রী হ্যাকের মতো দেখায়)SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'preg_replaceUPDATE foo ... WHERE pkey_id=...


8
এটি 2007 সাল থেকে একটি বৈশিষ্ট্য অনুরোধ: bugs.mysql.com/bug.php?id=27389 । আপনি যদি সত্যই এই বৈশিষ্ট্যটি চান, লগ ইন করুন এবং "আমাকে প্রভাবিত করে" বোতামটি ক্লিক করুন আশা করি এটি যথেষ্ট ভোট পাবে।
টিএমএস

4
@ টমাস: ২০০৯ সালে, আমি যখন এটির সন্ধান করছিলাম তখন আমি এটি করেছি। যেহেতু এটিতে শূন্য অগ্রগতি হয়েছে - দৃশ্যত এটি এত গুরুত্বপূর্ণ বৈশিষ্ট্য নয়। (BTW Postgres এটা আছে: stackoverflow.com/questions/11722995/... )
Piskvor ভবন বাম

1
সম্পর্কিত, সহজ, এই প্রশ্নের সংস্করণ: stackoverflow.com/questions/6942973/...
Kzqai

2
আমি তৈরি করেছি regexp_split(ফাংশন + পদ্ধতি) & regexp_replace, যা REGEXPঅপারেটরের সাথে প্রয়োগ করা হয় । সাধারণ অনুসন্ধানের জন্য, এটি কৌশলটি করবে। আপনি এটি এখানে খুঁজে পেতে পারেন - সুতরাং, এটি মাইএসকিউএল সঞ্চিত কোড সহ কোনও ইউডিএফ নয়। যদি আপনি কিছু বাগ খুঁজে পান যা জ্ঞাত সীমাবদ্ধতার আওতায় নেই - সমস্যাটি নির্দ্বিধায় উদ্বিগ্ন করুন।
আলমা দো

1
অন্য এসও থ্রেড থেকে এই লাইব্রেরিটি পাওয়া গেছে: github.com/mysqludf/lib_mysqludf_preg পুরোপুরি কার্যকরভাবে কাজ করে।
কাইল

উত্তর:


77

সঙ্গে মাইএসকিউএল 8.0+ আপনি নেটিভ ব্যবহার করতে পারে REGEXP_REPLACEফাংশন।

12.5.2 নিয়মিত এক্সপ্রেশন :

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

স্ট্রিং প্রতিস্থাপিত ঘটনার expr যে নিয়মিত প্যাটার্ন দ্বারা নির্দিষ্ট অভিব্যক্তি মেলে চাপড়ান প্রতিস্থাপন স্ট্রিং সঙ্গে repl , এবং আয় ফলে পংক্তি। তাহলে expr , চাপড়ান , অথবা repl হয় NULL, এর বিনিময়ে মান NULL

এবং নিয়মিত অভিব্যক্তি সমর্থন :

পূর্বে, মাইএসকিউএল নিয়মিত এক্সপ্রেশন অপারেটর ( REGEXP, RLIKE) সমর্থন করার জন্য হেনরি স্পেন্সার নিয়মিত অভিব্যক্তি গ্রন্থাগার ব্যবহার করে ।

আন্তর্জাতিক ইউনিকোড (আইসিইউ) জন্য আন্তর্জাতিক উপাদান ব্যবহার করে নিয়মিত এক্সপ্রেশন সমর্থন পুনরায় প্রয়োগ করা হয়েছে, যা সম্পূর্ণ ইউনিকোড সমর্থন সরবরাহ করে এবং মাল্টবাইট নিরাপদ। REGEXP_LIKE()ফাংশনের পদ্ধতিতে রেগুলার এক্সপ্রেশন ম্যাচিং সঞ্চালিত REGEXPএবং RLIKEঅপারেটরদের, যা এখন যে ফাংশন জন্য প্রতিশব্দের হয়। উপরন্তু, REGEXP_INSTR(), REGEXP_REPLACE(), এবং REGEXP_SUBSTR() ফাংশন ম্যাচ অবস্থানের এটি উপলব্ধ এবং যথাক্রমে প্রতিকল্পন এবং নিষ্কাশন সাবস্ট্রিং কার্য সম্পাদন,।

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

ডিবিফিডাল ডেমো


146

মাইএসকিউএল 8.0+ :

আপনি স্থানীয় REGEXP_REPLACEফাংশন ব্যবহার করতে পারেন ।

পুরানো সংস্করণ:

আপনি mysql-udf-regexp এর মতো একটি ব্যবহারকারী-সংজ্ঞায়িত ফাংশন ( UDF ) ব্যবহার করতে পারেন ।


3
ব্যবহারকারী সংজ্ঞায়িত কার্য হিসাবে REGEXP_REPLACE? প্রতিশ্রুতিবদ্ধ মনে হচ্ছে, এটি খতিয়ে দেখা হবে। ধন্যবাদ!
পিসকভোর 15:34-

15
দুর্ভাগ্যক্রমে mysql-udf-regexp মাল্টিবাইট অক্ষরের জন্য সমর্থন বলে মনে হচ্ছে না। regexp_replace ('äöõü', 'ä', '') রিয়েল টেক্সটের পরিবর্তে একটি দীর্ঘ সংখ্যার স্ট্রিং দেয়।
lkraav

3
মাইএসকিউএল নিজেই এর রেজিএক্স বৈশিষ্ট্যগুলি সহ মাল্টি-বাইট অক্ষর সমর্থন করে না।
ব্র্যাড

4
উইন্ডোজ ব্যবহারকারীরা: এখানে লিঙ্কিত ইউডিএফ লাইব্রেরিতে উইন্ডোজ সমর্থন ভাল বলে মনে হচ্ছে না। উল্লিখিত উইন্ডোজ ইনস্টলেশন পদ্ধতিটি আমার পক্ষে ভাল কাজ করে না।
জোনাথন

2
@lkraav আপনার নীচের lib_mysqludf_preg লাইব্রেরিটি দুর্দান্ত কাজ করার চেষ্টা করা উচিত। এটি ভার্বোজ সংস্করণ হিসাবে এটি একটি ডিফল্টরূপে একটি ফোঁটা ফেরত দেয় এবং আমি জানি না যে আপনার যদি আপনার ডিফল্ট হিসাবে মাল্টিবাইট চার্সেট থাকে: কাস্ট নির্বাচন করুন (টিআর হিসাবে) সিলেক্ট করুন utf8_unicode_ci থেকে (প্রিগ_রেপস নির্বাচন করুন ('/ ä /', '', 'öõüä') আর) টি
গিলিস্পি

124

পরিবর্তে মারিয়াডিবি ব্যবহার করুন। এটি একটি ফাংশন আছে

REGEXP_REPLACE(col, regexp, replace)

দেখুন MariaDB ডক্স এবং PCRE নিয়মিত প্রকাশ উন্নত

মনে রাখবেন আপনি রেজিএক্সএক্স গ্রুপিংও ব্যবহার করতে পারেন (আমি এটি খুব দরকারী বলে মনে করেছি):

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")এটি একবারে পুরো কলাম থেকে abcxyz-2 থেকে -2 সরিয়ে দেয়।
য়োশিয

27
একটি সম্পূর্ণ প্ল্যাটফর্ম পরিবর্তন করা সত্যিই একটি বাস্তব সমাধান নয়।
ডেভিড বাউকুম

3
@ ডেভিডবাউকাম মারিয়াডিবি মাইএসকিউএল-এর একটি ড্রপ-ইন প্রতিস্থাপন। সুতরাং এটি কোনও "প্ল্যাটফর্মের পরিবর্তন" নয় বরং একই যাত্রার জন্য আলাদা বিমান নির্বাচন করার মতো
বেনভোর্থ


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
আমার কাছে আপনার কাছে অদ্ভুত লাগছে যে আপনি এটির মতো সন্ধান করতে চান, আমি সেড-আই / ওল্ড স্ট্রিং / নতুন_তারা / জি '/ প্যাথ / টো / ডাম্প.এসকিএল
স্পেশাক

36
বড় ডেটা সেট, বা জায়গায় রেফারেনশিয়াল অখণ্ডতার সাথে খুব ঝুঁকিপূর্ণ এবং অযৌক্তিক: ডেটা সরাতে এবং তারপরে এটি আবার সন্নিবেশ করানোর জন্য আপনাকে অনুশীলন করে আপনার ডাটাবেসটি বন্ধ করে দিয়ে রেফারেন্সিয়াল অখণ্ডতা বন্ধ করতে হবে।
রাউল লুনা

5
অতীতে এই পদ্ধতিটি ব্যবহার করে, আমি রাউলের ​​সাথে আগ্রাসন করেছি, এটি খুব ঝুঁকিপূর্ণ। আপনার পাশাপাশি একেবারে নিশ্চিত হওয়া দরকার যে আপনার স্ট্রিংটি আপনার ডেটাসেটে কোনও জায়গায় নেই e
ডিম্বাশয়কর

1
@ স্পেশাকের উত্তরে কয়েক বছর দেরি হলেও আমি এই জাতীয় ফাইলটি অ্যাক্সেস করতে বেছে নেওয়ার কারণটি ছিল কারণ আমি উপরে বর্ণিত একই কারণে মূলত খুব ঘাবড়েছি। এমন সময় মনে হয়েছিল যে "ফাইলটি সন্ধান করুন" অংশটি "প্রতিস্থাপন" অংশ থেকে আলাদা করা কোডটি পড়ার আগে পড়া সহজ করে দেবে
রায়ান ওয়ার্ড

42

আমরা রেজেক্স ব্যবহার না করেই এই সমস্যাটি সমাধান করি এই কোয়েরিটি কেবল সঠিক ম্যাচের স্ট্রিং প্রতিস্থাপন করে।

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

উদাহরণ:

emp_id কর্মচারী_প্রথম নাম

1 জা

2 জয় অজয়

3 জা

ক্যোয়ারির ফলাফল কার্যকর করার পরে:

emp_id কর্মচারী_প্রথম নাম

1 এবি

2 এবিসি অজয়

3 এবি


@ অ্যালোমেলন দুটি জোড়া ডাবল কোটের জন্য কী?
কোডেকবয়

5
সে তার আগে এবং পরে ফাঁকা জায়গাগুলিতে কর্মচারী নামকরণ করছে। এটি তাকে (স্পেস) কর্ম-নাম (স্পেস) এর জন্য অনুসন্ধান-প্রতিস্থাপনের অনুমতি দেয়, যা নিয়োগের নামটি "জয়" এড়ানো এড়ায় যদি এর বৃহত্তর স্ট্রিংয়ের অংশ "অজয়" থাকে। তারপরে তিনি যখন কাজগুলি করেন তখন স্পেসগুলি ছাঁটাই করেন।
স্ল্যাম

42

আমি নিয়মিত এক্সপ্রেশন ব্যবহার করে স্ট্রিং প্রতিস্থাপন করতে সম্প্রতি একটি মাইএসকিউএল ফাংশন লিখেছি। আপনি আমার পোস্টটি নিম্নলিখিত স্থানে খুঁজে পেতে পারেন:

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')(নোবেসিডির 'রিটার্ন,' এবিসি 'নয়) এর মতো রেফারেন্সগুলির সাথে ডিল করে না ।
ইজজি

@ ফোবি অন্য কেউ এই উত্তরে তা করেছিলেন - লিঙ্কটি মারা যাওয়ার ক্ষেত্রে যেমন একটি রেফারেন্স হিসাবে;)
ইজজি

আমি উপরে উল্লিখিত কিছু সীমাবদ্ধতার কিছু সমাধান করার চেষ্টা করার জন্য এই পদ্ধতিটি পরিবর্তন করেছি। দয়া করে এই উত্তরটি দেখুন
স্টিভ চেম্বার্স

14

আমি এই বিষয়টি জানতে পেরে খুশি যেহেতু এই প্রশ্নটি জিজ্ঞাসা করা হয়েছিল, এখন একটি সন্তোষজনক উত্তর রয়েছে! এই ভয়ঙ্কর প্যাকেজটি একবার দেখুন:

https://github.com/mysqludf/lib_mysqludf_preg

নমুনা এসকিউএল:

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

এই প্রশ্নটির সাথে সম্পর্কিত হিসাবে আমি এই ব্লগ পোস্ট থেকে প্যাকেজটি পেয়েছি ।


13

আপডেট 2: আর মাইএসকিউএল 8.0-এ আরইজিএক্সপিপিপিএলসিএল সহ রেগেক্স ফাংশনগুলির একটি দরকারী সেট সরবরাহ করা হয়েছে। আপনি পূর্ববর্তী সংস্করণটি ব্যবহারে সীমাবদ্ধ না হলে এটি অপ্রয়োজনীয় উপর পড়ার রেন্ডার করে।


আপডেট 1: এখন এটি একটি ব্লগ পোস্টে পরিণত করেছে: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-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 ;

ডেমো

রেক্সটেস্টার ডেমো

সীমাবদ্ধতা

  1. সাবজেক্ট স্ট্রিং বড় হলে এই পদ্ধতিটি অবশ্যই কিছুটা সময় নিতে চলেছে। আপডেট: উন্নত দক্ষতার জন্য এখন ন্যূনতম এবং সর্বাধিক ম্যাচের দৈর্ঘ্যের পরামিতিগুলি যুক্ত হয়ে গেছে যখন এগুলি জানা যায় (শূন্য = অজানা / সীমাহীন)।
  2. এটি ক্যাপচারিং গ্রুপগুলি প্রতিস্থাপনের (যেমন , ইত্যাদি) প্রতিস্থাপনের অনুমতি দেয় না । যদি এই কার্যকারিতাটির প্রয়োজন হয় তবে দয়া করে এই উত্তরটি দেখুন যা প্রতিটি প্রাপ্ত মিলের মধ্যে গৌণ সন্ধান এবং প্রতিস্থাপনের ম্যাচে (বর্ধিত জটিলতার ব্যয়ে) প্রতিস্থাপনের জন্য ফাংশন আপডেট করে একটি কার্যপ্রণালী সরবরাহ করার চেষ্টা করে।\1\2
  3. যদি ^এবং / অথবা $প্যাটার্নে ব্যবহৃত হয় তবে এগুলি অবশ্যই যথাক্রমে একেবারে শুরুতে এবং একেবারে শেষ প্রান্তে থাকতে হবে - যেমন প্যাটার্নগুলি যেমন (^start|end$)সমর্থিত নয়।
  4. সামগ্রিক মিলটি লোভী বা অ-লোভী হওয়া উচিত কিনা তা নির্দিষ্ট করার জন্য একটি "লোভী" পতাকা রয়েছে। একক নিয়মিত অভিব্যক্তিতে (উদাঃ a.*?b.*) মধ্যে লোভী এবং অলস মিলনের মিশ্রণ সমর্থিত নয়।

ব্যবহারের উদাহরণ

ফাংশনটি নিম্নলিখিত স্ট্যাকওভারফ্লো প্রশ্নের উত্তরগুলির জন্য ব্যবহৃত হয়েছে:


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
না, এটি কাজ করবে না। কল্পনা করুন যে আপনার কলামটিতে'্যাসেডডেফআরআরএডআরপিআলএপিআরএপিআরএপিআরএপিআরএপিআরএলপিআরএপিএলসিপিএলপ্লেস রিপ্লেসমেন্ট "রয়েছে যেখানে আপনার উত্তরটির ফলস্বরূপ" এসএসডিফ্রেপ্লেসেন্ট রিপ্লেসমেন্ট "হবে যেখানে সঠিক উত্তরটি হবে" এসএসডিএফআর।
রায়ান শিলিংটন

1
@ রায়ান ... ঠিক এই কারণেই আমি বলেছি যে এটি খুব জ্ঞানী ছিল না ... আপনি যে ব্যবহারের ক্ষেত্রে এটি সরবরাহ করেছেন তা অবশ্যই ব্যর্থ হবে। সংক্ষেপে এটি 'রেজেক্স-জাতীয়' কাঠামো ব্যবহার করা খারাপ ধারণা। আরও খারাপ ... আপনি যদি ক্লজটি বাদ দেন তবে আপনার সমস্ত মানগুলি শূন্য হয়ে যাবে ...
এডি বি

1
আসলে রায়ান এই ক্ষেত্রে আপনি ভুল কারণ চিহ্নিতকারীরা কেবল শূন্য দৈর্ঘ্যের শব্দের 'সীমানা'র জন্য মিল খুঁজে পাবে তাই শব্দের আগে বা পরে সীমানা যুক্ত শব্দগুলি মিলবে ... এটি এখনও একটি খারাপ ধারণা যদিও ...
এডি বি

6

আমরা নীচে যেমন নির্বাচনী ক্যোয়ারিতে শর্তটি ব্যবহার করতে পারি:

মনে করুন যে "ABC", "ABC1", "ABC2", "ABC3", ... এর সাথে যে কোনও কিছুর জন্য, আমরা "নির্বাচন কমিশন" এর পরে REGEXP এবং IF () শর্তটি ব্যবহার করে SELECT প্রশ্নের সাথে প্রতিস্থাপন করতে চাই, আমরা এটি অর্জন করতে পারি ।

বাক্য গঠন:

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'

আরজিইএক্সপি রেফারেন্স: https://www.geeksforgeeks.org/mysql-regular-expressionions-regexp/


আপনাকে ধন্যবাদ :) 8
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.