我正在尝试编写一个正则表达式来筛选 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}
否定前瞻 (?! ... )
将使匹配失败(如果其中的内容匹配)。由于我们有 (?![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/