python - 我怎样才能找到一个字符串,它包含两个正则表达式之间的任何一个,除了 python 中的某个正则表达式?

标签 python regex

我正在尝试编写一个正则表达式来筛选 3mb 的文本并找到特定的字符串。目前它运行良好,除了一个问题。

我现在使用的表达方式是

pattern = re.compile(r'[A-Z]{4} \d{3}.{4,40} \(\d\)')

这有效地搜索了巨大的字符串,并找到了所有出现的 4 个大写 aplha 字符,后跟一个空格,后跟 3 个数字,后跟 4-40 个任何类型的字符,后跟一个空格,然后是 (n),其中 n 是任意数字。

我要找的是类似ACCT 220 会计原则 I (3)

这正是我想要的,只是它有时会过早地捕捉到模式。文档中有一些情况表明,一个类将先于模式应该开始的类。例如,我将以 BMGT 310.ACCT 220 会计原则 I (3)

结尾

我认为解决这个问题的一种方法是不允许模式在正则表达式的 .{4,40} 部分包含 4 个大写字母。我试过使用 ^ 无济于事。

例如,我尝试了 [A-Z]{4}\d{3}([^A-Z]{4}){4,40}\(\d\)但后来我得到了一个空列表,因为表达式没有找到任何东西。

我在想我还不太了解正则表达式的语法。如果有人知道如何修复我的表达式,以便它会找到 4 个大写字母后跟一个空格,后跟三个数字,后跟 4-40 个 NOT 包含的任何类型的字符的所有实例连续 4 个大写字母,后跟一个空格,然后是 (n),其中 n 是一个数字,这太棒了,非常感谢。

我知道这个问题可能相当令人困惑。如果您需要我提供更多信息,请告诉我。

最佳答案

如果您不想连续匹配 4 个大写字母,您可以使用否定先行,然后使用 {4,40} 一次匹配 1 个字符:

您当前工作的正则表达式的一部分:

.{4,40}

将更改为:

(?:(?![A-Z]{4}).){4,40}

regex101 demo

否定前瞻 (?! ... ) 将使匹配失败(如果其中的内容匹配)。由于我们有 (?![A-Z]{4}),如果一行中有 4 个大写字母,则匹配将失败。它们是零宽度断言,因此最终匹配不会受到任何影响,这也是为什么我仍在使用 . 进行主要匹配的原因。


一个可能有助于解释负前瞻如何工作以及如何理解零宽度断言的简单示例是:

w(?!o)

这个正则表达式将以方式匹配w(注意没有涉及o),整体below 但不是 word 中的 w

(?![A-Z]{4}). 将因此匹配 .,除非此 . 是大写字符后跟 3更多大写字符(使其成为连续的 4 个大写字符)。

现在要重复此 .,您不能只使用 (?![A-Z]{4}).{4,40},因为负先行只会适用到第一个 . 而不是其他的。因此,诀窍是将 (?![A-Z]{4}). 放在一个组中,然后重复:

((?![A-Z]{4}).){4,40}

最后,我更喜欢使用非捕获组 (?: ... ) 因为它们不存储捕获,所以它们使正则表达式更高效:

(?:(?![A-Z]{4}).){4,40}

关于python - 我怎样才能找到一个字符串,它包含两个正则表达式之间的任何一个,除了 python 中的某个正则表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20877746/

相关文章:

javascript - 如何在js中使用.match(regEx)仅获取没有分隔符的内部字符串?

c# - 获取具有多个句点的文件的文件扩展名

python - 在 for 循环期间对 list/dict 赋值有什么好处?

python - 窗口大小的滚动平均值是列值的间隔

java - 替换前两次出现的 '&' 字符之间的字符串

java字符串拆分正则表达式保留定界符

Javascript正则表达式允许在文本框中输入多个电话号码

python - 将字符计数转换为标记计数

python - 如何有效地将具有一定周期性的列表拆分为多个列表?

python - 如何在 python 中使用字典将多个单词替换为单个单词?