正则表达式负向前查找

2 投票
4 回答
76 浏览
提问于 2025-04-14 17:47

我想要一个正则表达式,它可以匹配所有以四个或更多数字结尾的地址,但这些数字不能出现在 'APT''BOX''APT ''BOX ' 之后。

所以它应该匹配以下情况:

HITME 1234
HITME 12345
HITME1234

但不应该匹配以下情况:

BOX 1234
BOX 12345
BOX4044
APT 1234
APT 12345
NONHIT123
NONHIT 123

我已经写了一个这样的表达式

(?<!(APT |BOX ))([0-9]{4,})$

但它没有正确工作。某种程度上,它还是匹配了那些不应该匹配的情况。

4 个回答

1

你可以尝试匹配下面这个正则表达式。

^(?:(?:BOX|APT) *\d{4,}|\D*\d{,3}|\D*(\d{4,}))$

如果这个字符串符合要求,捕获组1会包含字符串末尾的数字。

演示链接

这个表达式有三个部分,像是选择题。前两个部分匹配那些不合法的字符串,但不把它们抓住。第三部分则匹配并抓住合法字符串中的数字。所以,重点是要关注那些能抓住子字符串的匹配结果。(这可不是我发明的奇怪方法;这是个老掉牙的技巧,自古以来就有人在用。)

我们可以把这个表达式拆解成以下几个部分。

^                     # match the beginning of the string
(?:                   # begin a non-capture group
  (?:BOX|APT) *\d{4,} # match 'BOX' or 'APT' followed by 4 or more spaces
                      # followed by 4 or more spaces
|                     # or
  \D*\d{,3}           # match 0 or more non-digits, followed by 0 to 3 digits
|                     # or
  \D*                 # match 0 or more non-digits
  (                   # begin capture group 1
    \d{4,}            # match 4 or more digits
  )                   # end capture group 1
)                     # end non-capture group
$                     # match end of string

注意所有可变长度的匹配( *, \D*, \d{4,}\d{,3})都是 贪婪的,也就是说,它们会尽可能多地匹配字符。

1

你不能把 APTBOX 放在同一个回溯断言中,因为它们的长度必须相同。

另外注意,你的模式只会匹配数字。

你可以添加另一个回溯断言,使用另外两个选项,并确保匹配的开始位置左边没有直接的数字。

在匹配数字之前,我们不能使用单词边界 \b,因为你希望能匹配到 HITME1234

(?<!\bAPT |\bBOX )(?<!\bAPT|\bBOX)(?<!\d)[0-9]{4,}$

正则表达式演示

根据最后数字前允许的字符,你可以使用负向前瞻和单词边界来获取整个匹配,同时还能匹配到 BOXA 1234

这个模式确保从字符串的开头开始,后面没有跟着 BOX 或 APT,然后是可选的空格,最后是一个数字:

^(?!(?:BOX|APT)(?=[^\S\n]*\d))\w+[^\S\n]*\d{4,}$

正则表达式演示

0

简而言之,使用 ^(?!APT|BOX).*?([0-9]{4,})$


你的正则表达式 (?<!(APT |BOX ))([0-9]{4,})$ 匹配得不太对:

  • BOX 123452345 上匹配,因为它前面没有 APT BOX ,而是前面有 BOX 1
  • BOX40444044 上匹配,因为它前面没有 APT BOX ,而是前面有 BOX
  • APT 123452345 上匹配也是类似的原因。

你需要的正则表达式是 ^(?!APT|BOX).*?([0-9]{4,})$,可以这样理解:

  • ^(?!APT|BOX) - 字符串的开头不能跟着 APTBOX
  • .*? - 字符串中间可以有一些杂七杂八的东西,尽量少占用字符(比如在你的测试案例中 HITME
  • ([0-9]{4,})$ - 字符串末尾匹配的数字

撰写回答