簡體   English   中英

python正則表達式:匹配多個正則表達式之一

[英]python regular expression: match either one of several regular expressions

我有一個字符串和三個要匹配的模式,我使用python re包。 具體來說,如果找到模式之一,則輸出“不喜歡”,否則,輸出“喜歡”。 有關這三種模式的簡要信息:

模式1:檢查字符串中的所有字符是否均為大寫字母

模式2:檢查連續字符是否相同,例如AABB ...

pattern3:檢查是否存在XYXY模式, XY可以相同,並且該模式中的字母不必彼此相鄰。

當我分別編寫模式時,程序將按預期運行。 但是,當我使用交替組合3種模式時| ,結果是錯誤的。 我已經檢查了stackoverflow帖子,例如, 在這里這里 提供的解決方案對我不起作用。

這是可以正常工作的原始代碼:

import sys
import re

if __name__ == "__main__":
    pattern1 = re.compile(r"[^A-Z]+")
    pattern2 = re.compile(r"([A-Z])\1")
    pattern3 = re.compile(r"([A-Z])[A-Z]*([A-Z])[A-Z]*\1[A-Z]*\2")

    word = sys.stdin.readline()
    word = word.rstrip('\n')
    if pattern1.search(word) or pattern2.search(word) or pattern3.search(word):
        print("Dislikes")
    else:
        print("Likes")

如果我使用以下代碼將3種模式組合為一種,則可能是錯誤的:

import sys
import re

if __name__ == "__main__":

    pattern = r"([A-Z])[A-Z]*([A-Z])[A-Z]*\1[A-Z]*\2|([A-Z])\1|[^A-Z]+"

    word = sys.stdin.readline()

    word = word.rstrip('\n')
    if re.search(word, pattern):
        print("Dislikes")
    else:
       print("Likes")

如果我們將3種模式分別稱為p1p2p3 ,我還嘗試了以下組合:

pattern = r"(p1|p2|p3)"
pattern = r"(p1)|(p2)|(p3)"

但是它們也無法按預期工作。 結合它們的正確方法是什么?

測試用例:

  • “喜歡”: ABCABCDAABCBA
  • “不喜歡”: ABBC (模式2), THETXH (pattern3), ABACADA (pattern3), AbCD (模式1)

這是一個加入您的模式:

([^A-Z]+|([A-Z])\2|([A-Z])[A-Z]*([A-Z])[A-Z]*\3[A-Z]*\4)

那么,為什么行得通呢?

它由一個簡單的(p1|p2|p3)模式組成,其中p1p2p3是您之前定義的模式:

[^A-Z]+
([A-Z])\1
([A-Z])[A-Z]*([A-Z])[A-Z]*\1[A-Z]*\2

它可以分解為:

(
  [^A-Z]+
 |([A-Z])\2
 |([A-Z])[A-Z]*([A-Z])[A-Z]*\3[A-Z]*\
)

您遇到麻煩的問題是組的編號。

首先,當您組合p2p3 ,都引用\\1 ,但是后者在兩種模式中表示不同的事物。 因此, p3應該成為...\\2...\\3 ,因為之前還有一個附加組。

此外,由\\number引用的組索引按打開順序進行索引。 因此,與外部(...|...|...)的開口相對應的第一個括號被計為第一組, \\1將被引用為第一組。 當然,這不是您想要的。 但是此外,這還會給您帶來錯誤,因為\\1指向尚未關閉的組,因此尚未定義。

因此,索引應移位一個,分別變為\\2\\3\\4

此類A|B表達式通常嵌套在括號中,但實際上可以將其刪除,並將索引移回一個:

[^A-Z]+|([A-Z])\1|([A-Z])[A-Z]*([A-Z])[A-Z]*\2[A-Z]*\3

這是此模式的一個小例子:

import sys
import re

if __name__ == "__main__":
    pattern1 = re.compile(r"[^A-Z]+")
    pattern2 = re.compile(r"([A-Z])\1")
    pattern3 = re.compile(r"([A-Z])[A-Z]*([A-Z])[A-Z]*\1[A-Z]*\2")    
    pattern = re.compile(r"([^A-Z]+|([A-Z])\2|([A-Z])[A-Z]*([A-Z])[A-Z]*\3[A-Z]*\4)")

    while True:
        try:
            word = input("> ")
            print(pattern1.search(word))
            print(pattern2.search(word))
            print(pattern3.search(word))
            print(pattern.search(word))
        except Exception as error:
            print(error)

互動環節:

> ABC    # Matches no pattern
None
None
None
None

> ABCBA  # Matches no pattern
None
None
None
None

> ABBC   # Matches p2
None
<_sre.SRE_Match object; span=(1, 3), match='BB'> # p2 is matched
None
<_sre.SRE_Match object; span=(1, 3), match='BB'> # Jointure gives the same match

> ABACADA # Matches p3
None
None
<_sre.SRE_Match object; span=(0, 7), match='ABACADA'> # p3 is matched
<_sre.SRE_Match object; span=(0, 7), match='ABACADA'> # Jointure gives the same match

暫無
暫無

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

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