給定這個例子:
s = "Hi, domain: (foo.bar.com) bye"
我想分別創建一個匹配單詞和非單詞字串的正則運算式,即:
re.findall(regex, s)
# Returns: ["Hi", ", ", "domain", ": (", "foo.bar.com", ") ", "bye"]
我的方法是使用單詞邊界分隔符\b來捕獲由兩個單詞到非單詞開關系結的任何字串。從re模塊檔案:
\b\w被定義為 a和字符之間的邊界\W(反之亦然)
因此,我嘗試了第一步:
regex = r'(?:^|\b).*?(?=\b|$)'
re.findall(regex, s)
# Returns: ["Hi", ",", "domain", ": (", "foo", ".", "bar", ".", "com", ") ", "bye"]
問題是我不希望點 ( .) 字符也成為分隔符,我希望正則運算式將其foo.bar.com視為一個完整的單詞,而不是由點分隔的三個單詞。
我試圖找到一種在 dot 上使用負前瞻的方法,但沒有成功。
有沒有辦法做到這一點?
我不介意點在正則運算式中根本不是分隔符,它不必特定于域名。
我查看了正則運算式單詞邊界替代,使用單詞邊界捕獲而不在“點”和/或其他字符處停止,以及正則運算式單詞邊界不包括連字符,但它不適合我的情況,因為我不能使用空格作為分隔符條件。
從單詞邊界中排除一些字符是唯一讓我接近的字符,但我沒有設法達到它。
uj5u.com熱心網友回復:
您可以在以下位置使用此正則運算式findall:
\w (?:\.\w )*|\W
它會找到一個單詞,然后是 0 個或多個重復的點分隔單詞或 1 個非單詞字符。
代碼:
import re
s = "Hi, domain: (foo.bar.com) bye"
print (re.findall(r'\w (?:\.\w )*|\W ', s))
輸出:
['Hi', ', ', 'domain', ': (', 'foo.bar.com', ') ', 'bye']
uj5u.com熱心網友回復:
對于您的示例,您可以只拆分,[^\w.] 使用圍繞它的捕獲組將這些值保留在輸出中:
import re
s = "Hi, domain: (foo.bar.com) bye"
re.split(r'([^\w.] )', s)
# ['Hi', ', ', 'domain', ': (', 'foo.bar.com', ') ', 'bye']
如果您的字串可能以非單詞/空格字符結尾或結尾,您可以使用理解過濾掉串列中生成的空字串:
s = "!! Hello foo.bar.com, your domain ##"
re.split(r'([^\w.] )', s)
# ['', '!! ', 'Hello', ' ', 'foo.bar.com', ', ', 'your', ' ', 'domain', ' ##', '']
[w for w in re.split(r'([^\w.] )', s) if len(w)]
# ['!! ', 'Hello', ' ', 'foo.bar.com', ', ', 'your', ' ', 'domain', ' ##']
uj5u.com熱心網友回復:
如果這就是您的意思,環視可以讓您輕松說出“點,除非它的兩邊都被字母包圍”;
re.findall(r'(?:^|\b)(\w (?:\.\w )*|\W )(?!\.\w)(?=\b|$)', s)
或者只是“單詞邊界,除非它是一個點”:
re.findall(r'(?:^|(?<!\.)\b(?!\.)). ?(?=(?<!\.)\b(?!\.)|$)', s)
請注意,如果它是一個點,后者將跨越單詞邊界連接文本;因此,例如,'bye. '將被提取為一個字串。
(也許嘗試更準確地了解您的要求?)
演示:https ://ideone.com/dvQhFO
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/521229.html
標籤:Python正则表达式
