Python中的正则表达式:如何进行非匹配

2 投票
3 回答
16206 浏览
提问于 2025-04-16 13:04

我直接说吧:我有一个像这样的字符串(但有成千上万行)

Ach-emos_2
Ach. emos_54
Achėmos_18
Ąžuolas_4
Somtehing else_2

我需要删除那些不符合 a-ząčęėįšųūž 以及 _任何整数 的行(第三和第四行符合这个条件)。而且这个匹配应该不区分大小写。我觉得正则表达式应该是

[a-ząčęėįšųūž]+_\d+ #don't know where to put case insensitive modifier

但是,匹配那些不是字母(包括立陶宛字母)加下划线加整数的行的正则表达式应该是什么样的呢?我试过

re.sub(r'[^a-ząčęėįšųūž]+_\d+\n', '', words)

但是效果不好。

提前谢谢你,如果我的英语不太好,抱歉。

3 个回答

0

不太清楚Python是怎么处理修饰符的,但如果你想要直接在原来的内容上进行修改,可以用类似下面的方式(不区分大小写):

注意:这些字符中有些是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
0

首先,根据你给出的例子,每一行的结尾都是下划线加上数字,所以你只需要反转原来的匹配方式。如果这个例子不太代表真实情况,那么反转匹配可能会得到这样的结果:

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)])
5

关于让匹配不区分大小写,你可以使用 I 或者 IGNORECASE 这些标志,来自 re 模块,比如在编写你的正则表达式时:

regex = re.compile("^[a-ząčęėįšųūž]+_\d+$", re.I)

至于去掉那些不符合这个正则表达式的行,你可以简单地构建一个新的字符串,只包含那些符合的行:

new_s = "\n".join(line for line in s.split("\n") if re.match(regex, line))

撰写回答