Python 中的正则表达式。不匹配
Posted
技术标签:
【中文标题】Python 中的正则表达式。不匹配【英文标题】:Regex in Python. NOT matches 【发布时间】:2011-07-09 13:06:07 【问题描述】:我会直接说:我有一个这样的字符串(但有数千行)
Ach-emos_2
Ach. emos_54
Achėmos_18
Ąžuolas_4
Somtehing else_2
我需要删除与a-z
和ąčęėįšųūž
加上_
加上any integer
不匹配的行(第 3 和第 4 行与此匹配)。这应该不区分大小写。我认为正则表达式应该是
[a-ząčęėįšųūž]+_\d+ #don't know where to put case insensitive modifier
但是应该如何看待匹配非 alpha(和立陶宛字母)加上下划线加整数的行的正则表达式?我试过了
re.sub(r'[^a-ząčęėįšųūž]+_\d+\n', '', words)
但不好。
提前致谢,如果我的英语不太好,请见谅。
【问题讨论】:
【参考方案1】:不知道python是如何做修饰符的,但是要就地编辑,使用类似这样的东西(不区分大小写):
edit 请注意,其中一些字符是 utf8。要使用文字表示,您的编辑器和语言必须支持这一点,否则使用字符类中的 \u.. 代码(推荐)。
s/(?i)^(?![a-ząčęėįšųūž]+_\d+(?:\n|$)).*(?:\n|$)//mg;
正则表达式在哪里:r'(?i)^(?![a-ząčęėįšųūž]+_\d+(?:\n|$)).*(?:\n|$)'
替换是 ''
修饰符是多行和全局的。
细分:修饰符是全局和多行的
(?i) // case insensitive flag
^ // start of line
(?![a-ząčęėįšųūž]+_\d+(?:\n|$)) // look ahead, not this form of a line ?
.* // ok then select all except newline or eos
(?:\n|$) // select newline or end of string
【讨论】:
【参考方案2】:首先,给定您的示例输入,每一行都以下划线 + 整数结尾,因此您真正需要做的就是反转原始匹配。如果这个例子没有真正的代表性,那么反转匹配可能会得到这样的结果:
abcdefg_nodigitshere
但是你可以这样子过滤:
import re
mydigre = re.compile(r'_\d+$')
myreg = re.compile(r'^[a-ząčęėįšųūž]+_\d+$', re.I)
for line in inputs.splitlines():
if re.match(myreg, line):
# do x
elif re.match(mydigre, line):
# do y
else:
# line doesn't end with _\d+
另一种选择是使用 Python 集。仅当您的所有行都是唯一的(或者您不介意消除重复行)并且您不关心顺序时,这种方法才有意义。它可能也有很高的内存成本,但可能很快。
all_lines = set([line for line in inputs.splitlines()])
alpha_lines = set([line for line in all_lines if re.match(myreg, line)])
nonalpha_lines = all_lines - alpha_lines
nonalpha_digi_lines = set([line for line in nonalpha_lines if re.match(mydigire, line)])
【讨论】:
【参考方案3】:至于使匹配不区分大小写,您可以使用 re
模块中的 I
或 IGNORECASE
标志,例如在编译正则表达式时:
regex = re.compile("^[a-ząčęėįšųūž]+_\d+$", re.I)
至于删除与此正则表达式不匹配的行,您可以简单地构造一个由 匹配的行组成的新字符串:
new_s = "\n".join(line for line in s.split("\n") if re.match(regex, line))
【讨论】:
以上是关于Python 中的正则表达式。不匹配的主要内容,如果未能解决你的问题,请参考以下文章