簡體   English   中英

python中的“否定”模式匹配

[英]'negative' pattern matching in python

我有以下輸入,

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:
    matchObj = re.search("^(?!OK) | ^(?!\\.)", item)
    if matchObj:
        print "got item "  + item

但它不起作用,因為它不產生任何輸出。

看看它在行動

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

不要忘記在否定前瞻之后放置.* ,否則您將無法獲得任何匹配 ;-)

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

使用否定匹配。 (另請注意,默認情況下,正則表達式中的空格很重要,因此不要將內容隔開。或者,使用re.VERBOSE 。)

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

為什么不匹配 OK SYS 行而不返回它。

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

如果這是一個文件,您可以簡單地跳過第一行和最后一行,並使用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]
and(re.search("bla_bla_pattern", str_item, re.IGNORECASE) == None)

正在工作。

你也可以在沒有負面展望的情況下做到這一點。 您只需要在要提取的表達式部分添加括號。 這個帶括號的結構被命名為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 的末尾,我們尋找一個點. ,但我們也不想捕獲它。

PS:我發現這個答案對於理解群體的力量非常有幫助。 https://stackoverflow.com/a/3513858/4333811

如果 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]))

但是,如果這是一個非常大的字符串,您可能會遇到內存問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM