簡體   English   中英

正則表達式解析 python 中的對話

[英]Regex to parse dialogue in python

我想從 python 中的文件中解析三種類型的行:

"Name" "Something to say !"
"Just a descriptive sentence"
name "Something to say !"

我想得到名字和句子,如果沒有名字,只有句子。 我閱讀了文件的每一行,使用re來查看正則表達式是否匹配。 它工作得很好,除了這個:

"Name" "Something to say !"

它只是返回整個事物而不是兩個部分。

這是我的正則表達式:

r"(\"[a-zA-z?]*\"|[a-zA-z]*)\s\"(.+)\""

您可以使用帶有反向引用"捕獲組來匹配或不匹配隨附的雙引號。

然后你可以使包括空白字符在內的整個第一部分成為可選的,並在雙引號之間匹配第二部分。

請注意, [a-zA-z] 匹配的次數多於[a-zA-Z]? 在字符 class 內部與問號字面匹配。

比賽分在第 1 組和第 3 組。

(?:(("?)[a-zA-Z]+\2)\s)?("[^"]+")
  • (?:非捕獲組
    • (捕獲組 1
      • ("?)在組 2 中捕獲一個可選的"
      • [a-zA-Z]+匹配 a+ 次 a char a-zA-Z a
      • \2對組 2 的反向引用以完全匹配該組中的匹配項
    • )\s關閉第 1 組並匹配一個空白字符
  • )? 關閉非捕獲組並使其可選
  • ("[^"]+")捕獲組 3 ,匹配從""

查看正則表達式演示| Python 演示

使用 re.finditer 循環匹配的示例:

import re

regex = r"(?:((\"?)[a-zA-Z]+\2)\s)?(\"[^\"]+\")"
s = ("\"Name\" \"Something to say !\"\n"
            "\"Just a descriptive sentence\"\n"
            "name \"Something to say !\"\n"
            "\"Name\" \"Something to say !\"")

matches = re.finditer(regex, s)
for matchNum, match in enumerate(matches, start=1):
        print(f"Name: {match.group(1)} Sentence: {match.group(3)}")

Output

Name: "Name" Sentence: "Something to say !"
Name: None Sentence: "Just a descriptive sentence"
Name: name Sentence: "Something to say !"
Name: "Name" Sentence: "Something to say !"

解決方案

在我看來,您最好的選擇是使用命名捕獲組。 就是這樣:

import re

lines = [
    '"Name" "Something to say !"',
    '"Just a descriptive sentence"',
    'name "Something to say !"'
    ]

p = re.compile(r"(\"?(?P<part1>.+?)\"? )?(\"(?P<part2>.+)\")")

for line in lines:
    m = p.search(line)
    print(m["part1"])
    print(m["part2"])

output 將是

Name
Something to say !
None
Just a descriptive sentence
name
Something to say !

解釋

正則表達式(\"?(?P<part1>.+?)\"? )?(\"(?P<part2>.+)\")由兩個主要部分組成。 我將通過第一個 go (\"?(?P<part1>.+?)\"? )? . 第二個非常相似。

  • 外部組(...)? 使用“零或更多”量詞? . 因此,在您的第二種情況下,只有“part2”捕獲組將處於活動狀態。
  • 在該組中,引號還標有“零或多個”量詞以涵蓋您的第三種情況: \"?
  • 部分(?P<part1>.+?)匹配引號之間的文本並指定名稱“part1”以便於訪問。
    • . 匹配所有符號
    • +? 惰性匹配前面的一個或多個(盡可能多的字符,盡可能少)。 這是從匹配中排除第二個引號所必需的。

使用此正則表達式,您可以通過方括號語法訪問命名捕獲組的內容,如上面的代碼所示。

捕捉報價

如果您不僅要捕獲引號中的文本,還要捕獲引號本身,只需將\"移動到命名的捕獲組中,如下所示: ((?P<part1>\"?.+?\")? )?((?P<part2>\".+\"))

暫無
暫無

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

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