正则表达式不匹配正确的字符串
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'
永远不会匹配任何字符串,因为 c
和 D
之间没有单词边界,因为两个字符都是字母,即单词字符。如果要搜索整个单词Mc Donalds
,您将使用\bMc Donalds\b
。如果您需要匹配非单词字符中的任何内容,您可以使用(?<!\w)my search phrase(?!\w)
。以上是关于正则表达式不匹配正确的字符串的主要内容,如果未能解决你的问题,请参考以下文章
如何用正则表达式 匹配正确的imei串号呢!imei格式:由0-9数字组成的15或者17位的串号?