[英]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 ,匹配從"
到"
使用 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.