如何在MySQL正则表达式中引用捕获组?

39

如何在MySQL中使用正则表达式引用一个组? 我尝试了:

REGEXP '^(.)\1$'

但是它不起作用。 如何解决?


请发布完整的查询。 - nobody
我想知道如何做到这一点,这只是一个例子。SELECT * FROM table WHERE fields REGEXP '^test(.)\1$' - The Mask
1
@The Mask:您到底想做什么? - Shef
需要从变量中提取“aa”,例如:在JavaScript中,可以这样实现:var str = "aa bd ed"; var result = str.match(/(.)\1/); //aa,a - The Mask
1
当您澄清问题时,请编辑问题而不是发布评论。总之,问题中拥有比评论更多的格式化能力。 - Jonathan Leffler
在正则表达式中使用捕获组就像这个例子一样是没有意义的。请澄清问题。 - Sybille Peters
4个回答

81

(虽然这是一个旧问题,但它是最优秀的搜索结果)

对于 MySQL 8:

SELECT REGEXP_REPLACE('stackoverflow','(.{5})(.*)','$2$1');
-- "overflowstack"

您可以使用()创建捕获组,并使用$1$2等引用它们。

对于MariaDB,使用\\1\\2等来进行捕获,在REGEXP_REPLACE中完成。


2
对我来说,这在8.0.19中并没有按预期工作 - 怀疑可能存在错误。 (而且似乎奇怪的是,在文档中似乎没有提到。) - Steve Chambers
1
非常感谢,这解决了我复杂/特定的数据提取问题。我需要从一个混乱的“文本”类型列中提取电子邮件(其中包含太多不必要的HTML标记),我所做的就是从中提取电子邮件地址:SELECT REGEXP_Replace(description,'(.mailto:)(.+)(">.)', '$2') AS Email FROM tblBigMarkup; - Eddie Kumar
8
在MariaDB中,用\1代替$1。 "替换字符串可以使用反向引用形式的子表达式\N,其中N是从1到9的数字。" (https://mariadb.com/kb/en/regexp_replace/) - Jared Beck
1
顶部搜索结果...是为了什么? - osullic
1
+1 这在 MySQL 8.0.26 的文档中没有讨论。https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-replace - user189198
显示剩余2条评论

25

你不能在MySQL中引用正则表达式捕获组,没有方法。


1
+1 优秀的回答。他们说:“向后引用是一个可怕的错误,会对高效实现带来重大问题。它们还有点含糊不清('a((b)\2)d' 是否匹配 'abbbd'?)。避免使用它们。” 在 http://linux.die.net/man/7/regex 中,因此我认为缺少后向引用功能是一个错误。 - d5e5
3
@d5e5,你的意思是这个bug是一种特性吗? - light24bulbs

0

您可以通过在查询中嵌套函数调用来解决此问题。假设您的列中有以下字符串:

'100 SOME ST,THE VILLAGES,FL 32163,USA'

并且您想要捕获城市名称。如果MySQL支持它,像这样的捕获组将起作用(但它不支持):

'^[0-9A-Z\s]+,\s*([a-zA-Z\s]*)'

您可以嵌套函数调用以剥离您不需要的部分,然后像这样获取您需要的部分:

SELECT REGEXP_SUBSTR(REGEXP_REPLACE(column_name, '^[0-9\\sA-Z]+,', ''), '^[0-9\\sA-Z]+') FROM table_name;

THE VILLAGES

...


0

旧问题,但它出现在我的搜索中,我找到了答案。您可以使用带有反向引用的Rlike。在MySQL 5.7上测试过

#replace 'aa' with column name
SELECT 'aa' RLIKE '^(.)\1$';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接