【问题标题】:regex not working correctly when the test is fine测试正常时正则表达式无法正常工作
【发布时间】:2019-01-21 11:45:58
【问题描述】:

对于我的数据库,我有一个公司编号列表,其中一些以两个字母开头。我创建了一个正则表达式,它应该从查询中消除这些,并且根据我的测试,它应该。但是在执行时,结果仍然包含带字母的数字。

这是我在 https://www.regexpal.com 上测试过的正则表达式

([^A-Z+|a-z+].*)

我已经针对 SC08093、ZC000191 和 NI232312 等众多变体对其进行了测试,这些变体在测试中不应该匹配且不匹配,这很好。

我的 sql 查询看起来像;

SELECT companyNumber FROM company_data 
WHERE companyNumber ~ '([^A-Z+|a-z+].*)' order by companyNumber desc

总结一下,像 SC08093 这样的字符串不应该匹配,因为它们以字母开头。

我已经阅读了 postgres 的文档,但我似乎找不到任何关于此的内容。我不确定我在这里缺少什么。谢谢。

【问题讨论】:

  • 试试WHERE companyNumber NOT SIMILAR TO '[A-Za-z]{2}%'
  • 谢谢你,成功了。如果可以的话,您能否解释一下为什么这行得通而我的正则表达式却行不通?
  • 您的正则表达式可能没有达到您的预期 - [^A-Z+|a-z+] 将匹配一个 single 字符,该字符既不是小写字母,也不是大写字母,也不是文字 +也不是文字“|” .

标签: sql regex postgresql


【解决方案1】:

~ '([^A-Z+|a-z+].*)' 不起作用,因为这是一个 [^A-Z+|a-z+].* 正则表达式匹配操作,即使在 部分 匹配时也会返回 true(正则表达式匹配操作不需要完整的字符串匹配,因此模式可以匹配字符串中的任何位置)。 [^A-Z+|a-z+].* 匹配从AZ 的字母、+,|or a letter fromatoz`,然后是任意数量的任意零个或多个字符,位于字符串中的任意位置。

你可以使用

WHERE companyNumber NOT SIMILAR TO '[A-Za-z]{2}%'

online demo

这里,NOT SIMILAR TO 返回 SIMILAR TO 操作的逆结果。这个SIMILAR TO 运算符接受几乎是正则表达式模式的模式,但也类似于常规通配符模式。 NOT SIMILAR TO '[A-Za-z]{2}%' 表示所有以两个 ASCII 字母 ([A-Za-z]{2}) 开头并在 (%) 之后有任何内容的记录不返回,所有其他记录都将返回。请注意,SIMILAR TO 需要完整的字符串匹配,与 LIKE 相同。

【讨论】:

  • 谢谢你,成功了。如果可以的话,您能否解释一下为什么这行得通而我的正则表达式却行不通?
  • @KieranDee 我希望我添加了足够的细节。我认为SIMILAR TO 最适合您的任务。如果您的条件变得更加具体,您可以考虑使用~ 运算符。然后,不要忘记 ^ 标记字符串的开头,如果需要,$ 作为字符串锚点的结尾。
  • 感谢您的解释。所以即使字符串的任何部分与正则表达式匹配,postgres 基本上也会返回它。这意味着我必须将整个字符串与正则表达式匹配,而不是其中的一部分,至少对于我的正则表达式。
【解决方案2】:

您的模式:[^A-Z+|a-z+].* 表示“至少某些字符不是 A-Z 的字符串” - 要将其扩展到整个字符串,您需要使用 S-Man 所示的锚定正则表达式(用 @ 定义的组顺便说一句,987654322@ 并不是必需的)

我可能会使用一个正则表达式来指定需要的有效模式,然后改用!~

where company !~ '^[0-9].*$'

^[0-9].*$ 表示“仅由数字组成”,!~ 表示“不匹配”

where not (company ~ '^[0-9].*$')

【讨论】:

    【解决方案3】:

    不以字母开头的可以用

    WHERE company ~ '^[^A-Za-z].*'
    

    demo: db<>fiddle

    第一个^ 标志着开始。 [^A-Za-z] 表示“无字母”(包括大小写字母)。


    编辑:[A-z]更改为更精确的[A-Za-z] (Why is this regex allowing a caret?)

    【讨论】:

    • [^A-z] 实际上并不意味着没有字母。这意味着no letter, [, \, ], ^, _ and ` chars。见the [A-z] char range
    • @WiktorStribiżew 是的,当然你是对的。在这种情况下,另一种解决方案也是错误的,因为它总是以数字开头。那是 TO no 准确定义其用例的时候。
    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多