在 python 中结合正面和负面前瞻

Combining positive and negative lookahead in python

我正在尝试提取满足许多条件的标记,我正在使用前瞻来实现以下两个条件:

  1. 令牌必须是 numeric/alphanumeric(即,它们必须至少有一个数字)。它们可以包含一些特殊字符,例如 - '-','/','\','.','_' 等,

我想匹配如下字符串:165271agya678yah@123kj*12-

  1. 令牌不能包含连续的特殊字符,例如:ajh12-&

我不想匹配如下字符串:ajh12-&671%&i^

我对第一个条件使用正前瞻:(?=\w*\d\w*),对第二个条件使用负前瞻:(?!=[\_\.\:\;\-\\/\@\+]{2})

我不确定如何组合这两个先行条件。

任何建议都会有所帮助。提前致谢。

编辑 1 :

我也想提取属于较大字符串一部分的完整标记(即,它们可能出现在字符串中间)。

我想匹配字符串中的所有标记: 165271 agya678 yah@123 kj*12-

字符串中标记的

和 none(甚至不是标记的一部分):ajh12-& 671%&i^

为了强制正则表达式考虑整个字符串,我还在上面的正则表达式中使用了 \b(?=\b\w*\d\w*\b)(?!=\b[\_\.\:\;\-\\/\@\+]{2}\b)

您可以使用

^(?!=.*[_.:;\-\\/@+*]{2})(?=[^\d\n]*\d)[\w.:;\-\\/@+*]+$

Regex demo

否定先行 (?=[^\d\n]*\d) 匹配除数字以外的任何字符或换行符使用否定字符 class,然后匹配数字。

请注意,您还必须添加 * 并且大多数字符不必在字符 class.

中转义

使用对比,您还可以将第一个 .* 变成否定字符 class 以防止一些回溯

^(?!=[^_.:;\-\\/@+*\n][_.:;\-\\/@+*]{2})(?=[^\d\n]*\d)[\w.:;\-\\/@+*]+$

编辑

没有锚点,您可以在左侧 (?<!\S) 和右侧 (?!\S)

使用空白边界
(?<!\S)(?!=\S*[_.:;\-\\/@+*]{2})(?=[^\d\s]*\d)[\w.:;\-\\/@+*]+(?!\S)

Regex demo

您可以使用多个前瞻性断言来仅捕获

  1. (?!.*(?:\W|_){2,}.*) - 没有连续的特殊字符和
  2. (?=.*\d.*) - 至少有一位数字
^(?!.*(?:\W|_){2,}.*)(?=.*\d.*).*$