正则表达式不匹配正确的字符串

Posted

技术标签:

【中文标题】正则表达式不匹配正确的字符串【英文标题】:Regex not matching correct string 【发布时间】:2018-05-16 07:19:02 【问题描述】:

我正忙于为特定商家名称构建查找表。我尝试使用以下正则表达式,但它返回的结果少于 Netezza SQL 中的标准“like”函数。请参考以下:

SQL Like 函数:其中 trim(upper(a.MRCH_NME)) like '%CNA %' -- 返回 4622 个匹配项

Netezza SQL 中的正则表达式函数: where array_combine(regexp_extract_all(trim(upper(a.MRCH_NME)),'.*CNA\s','i'),'|') = ' CNA' -- 返回 2226 个匹配项

查看了两个结果集,发现如下字符串不匹配:

!C CNA INT ARR
*CNA PLATZ 0400
015764 CNA CRAD
C#CNA PARK 0

我使用了以下正则表达式:/.*CNA\s'/

知道为什么上述字符串没有作为匹配项返回吗?

谢谢。

【问题讨论】:

我认为你需要\\s[[:space:]]。另请注意,\s 不仅仅匹配空格。 累积。 to this reference, \s 匹配 一个空白字符。空白定义为[\t\n\f\r\pZ].。因此,您只能将 '.*CNA ''i'/ '(?i).*CNA ' 进行比较 谢谢,感谢您的快速回复。马上试试 【参考方案1】:

您可能应该使用regexp_like

SELECT *
FROM yourTable
WHERE REGEXP_LIKE(MRCH_NME, 'CNA[ ]', 'i');

这在逻辑上与使用LIKE 的以下查询相同:

SELECT *
FROM yourTable
WHERE MRCH_NME LIKE '%CNA ';

【讨论】:

谢谢,我替换了函数,但我现在没有得到任何匹配。我应该考虑使用不同的正则表达式吗? 我使用了以下函数并且它起作用了:regexp_like(trim(upper(a.MRCH_NME)),'.*CNA\s')。我也会试试你发布的新的。非常感谢快速响应并帮助蒂姆 哦...是的,我更改了答案以使正则表达式不区分大小写。 这里使用.* 没有意义,REGEXP_LIKE 也可以找到部分匹配项。所以,WHERE REGEXP_LIKE(MRCH_NME, 'CNA ', 'i'); 就足够了。除非 CNA 应该只是一个完整的单词,否则可以使用 WHERE REGEXP_LIKE(MRCH_NME, '\\bCNA\\b', 'i');(我假设 Netezza 正则表达式是 ICU 驱动的)。 你好维克托。感谢您的答复。 CNA 是商家的名称。我的最终目标是构建一个正则表达式,它可以从包含数百万不同商家的表中提取有问题的特定商家,并消除商家方面的所有噪音,例如在较大名称中包含 CNA 的商家。 WHERE REGEXP_LIKE(MRCH_NME, '\\bCNA\\b', 'i');只需更改这部分 '\\bCNA\\b' 中的 CNA,此表达式是否可以为不同的商家互换?【参考方案2】:

在我看来,问题更多在于您的代码而不是正则表达式。看:like '%CNA %' 返回所有 包含 CNA 子字符串的条目,该子字符串后跟条目内任意位置的文字空格。 '.*CNA\s' 正则表达式匹配除换行符以外的任何 0+ 字符,后跟 CNA 和 **任何空白字符*。

累加。 to this reference, \s 匹配”一个空格字符。空格定义为[\t\n\f\r\pZ]

因此,您实际上应该只使用

WHERE REGEXP_LIKE(MRCH_NME, 'CNA ', 'i')

或者,最好使用单词边界检查:

WHERE REGEXP_LIKE(MRCH_NME, '\bCNA\b', 'i')

其中\b 标志着从单词到非单词以及从非单词到单词字符的转换,从而确保了整个单词的搜索并证明了正则表达式的使用。

如果您不需要将商家名称作为一个完整的单词进行匹配,使用正则的LIKE'%CNA %',应该会更高效。

【讨论】:

感谢您修改后的答案和解释。我非常感谢对这个问题的帮助和耐心。我不明白的是 '\bCNA\b' 语法:假设商家名称有多个单词,例如“Mc Donalds”,那么表达式 '\bMc\bDonalds\b' 或 '\bMc Donalds\b' 会作为\b 表示单词边界正确吗?我要创建一个尽可能通用的表达式 @Atlas_Apple 我建议学习\b word boundary 参考。它不使用文本,它只断言字符串内的某个位置。 '\bMc\bDonalds\b' 永远不会匹配任何字符串,因为 cD 之间没有单词边界,因为两个字符都是字母,即单词字符。如果要搜索整个单词Mc Donalds,您将使用\bMc Donalds\b。如果您需要匹配非单词字符中的任何内容,您可以使用(?<!\w)my search phrase(?!\w)

以上是关于正则表达式不匹配正确的字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何用正则表达式 匹配正确的imei串号呢!imei格式:由0-9数字组成的15或者17位的串号?

匹配一个键值对的正则表达式问题,在线等,正确给加分

javascript 正则表达式匹配任何脚本中所有非单词字符的正确正则表达式范围是多少?

如果字符串完全符合定义,则匹配正则表达式

正则表达式在 C# 中匹配,但在 java 中不匹配

R 正则表达式不匹配所有连字符