regex Python中的“负”模式匹配

vlf7wbxs  于 2023-04-13  发布在  Python
关注(0)|答案(8)|浏览(125)

我有以下输入,

OK SYS 10 LEN 20 12 43
1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt
.

我想提取所有的输入 * 除了 * 包含“OK SYS 10 LEN 20“的行和包含一个"."(点)的最后一行。

1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt.1234 /data/c13af4/f.txt

我尝试了以下方法,

for item in output:
    match_obj = re.search("^(?!OK) | ^(?!\\.)", item)
    if match_obj :
        print("got item " + item)

但是它不起作用,因为它不产生任何输出。

szqfcxe2

szqfcxe21#

in action

match_obj = re.search("^(?!OK|\\.).*", item)

别忘了在负向前看后面加上.*,否则你将得不到任何匹配

jq6vz3qz

jq6vz3qz2#

使用负匹配。(还要注意,默认情况下,正则表达式中的空格是重要的,所以不要用空格隔开。或者,使用re.VERBOSE。)

for item in output:
    match_obj = re.search("^(OK|\\.)", item)
    if not match_obj:
        print("got item " + item)
oxcyiej7

oxcyiej73#

if not (line.startswith("OK ") or line.strip() == "."):
    print(line)
cx6n0qe3

cx6n0qe34#

为什么不匹配OK SYS行而不返回它呢?

for item in output:
    match_obj = re.search("(OK SYS|\\.).*", item)
    if not match_obj :
        print("got item " + item)
nbewdwxp

nbewdwxp5#

如果这是一个文件,您可以简单地跳过第一行和最后一行,并使用csv读取其余部分:

>>> s = """OK SYS 10 LEN 20 12 43
... 1233a.fdads.txt,23 /data/a11134/a.txt
... 3232b.ddsss.txt,32 /data/d13f11/b.txt
... 3452d.dsasa.txt,1234 /data/c13af4/f.txt
... ."""
>>> stream = StringIO.StringIO(s)
>>> rows = [row for row in csv.reader(stream,delimiter=',') if len(row) == 2]
>>> rows
[['1233a.fdads.txt', '23 /data/a11134/a.txt'], ['3232b.ddsss.txt', '32 /data/d13f11/b.txt'], ['3452d.dsasa.txt', '1234 /data/c13af4/f.txt']]

如果它是一个文件,那么你可以这样做:

with open('myfile.txt','r') as f:
   rows = [row for row in csv.reader(f,delimiter=',') if len(row) == 2]
ykejflvf

ykejflvf6#

and(re.search("bla_bla_pattern", str_item, re.IGNORECASE) == None)

正在起作用

h79rfbju

h79rfbju7#

你也可以不使用负向预测,你只需要在你想要提取的表达式部分加上括号,这个带括号的结构被命名为group
让我们来写Python代码:

string = """OK SYS 10 LEN 20 12 43
1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt
.
"""

search_result = re.search(r"^OK.*\n((.|\s)*).", string)

if search_result:
    print(search_result.group(1))

输出为:

1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt

^OK.*\n将找到第一行OK语句,但我们不想提取它,所以不带括号。接下来是我们想要捕获的部分:((.|\s)*),所以把它放在括号里。在regexp的末尾,我们寻找一个点.,但我们也不想捕获它。
P.S:我发现这个答案对理解群体的力量非常有帮助。https://stackoverflow.com/a/3513858/4333811

8oomwypt

8oomwypt8#

如果OK行是第一行,最后一行是点,你可以考虑像这样把它们切掉:

TestString = '''OK SYS 10 LEN 20 12 43
1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt
.
'''
print('\n'.join(TestString.split()[1:-1]))

但是,如果这是一个非常大的字符串,您可能会遇到内存问题。

相关问题