[英]Regex matching on full matched substring with constrains in Python
因為這是一個正則表達式的問題。 這是一個潛在的重復問題。
考慮那些給定的字符串
test_str = [
"bla bla google.com bla bla", #0
"bla bla www.google.com bla bla", #1
"bla bla api.google.com bla bla", #2
"google.com", #3
"www.google.com", #4
"api.google.com", #5
"http://google.com", #6
"http://www.google.com", #7
"http://api.google.com", #8
"bla bla http://www.google.com bla bla", #9
"bla bla https://www.api.google.com bla bla" #10
]
我想要的回報是google.*
或www.google.*
但不是api.google.*
。 這意味着,在上述情況下,2,5,8,10不應該返回任何匹配。
我已經嘗試了幾個正則表達式,但我找不到一行正則表達式字符串來執行此任務。 這是我試過的。
re.compile("((http[s]?://)?www\.google[a-z.]*)") # match 1,4,7,9
re.compile("((http[s]?://)?google[a-z.]*)") # match all
re.compile("((http[s]?://)?.+\.google[a-z.]*)") # match except 0,3,6
re.compile("((http[s]?://)?!.+\.google[a-z.]*)") # match nothing
在這里,我正在尋找一種忽略*.google.*
除了www.google.*
和google.*
。 但是在找到獲取*.google.*
的方法時我陷入困境。
PS:我用split()
找到了一種O(n ** 2)方法來解決這個問題。
r = re.compile("^((http[s]?://)?www.google[a-z.]*)|^((http[s]?://)?google[a-z.]*)")
for s in test_str:
for seg in s.split():
r.findall(seg)
你可以用
(?<!\S)(?:https?://)?(?:www\.)?google\.\S*
請參閱正則表達式演示 。
細節
(?<!\\S)
- 前面有一個空格或字符串開頭的位置(注意你也可以在這里使用(?:^|\\s)
,以便更明確) (?:https?://)?
- 與https://
或http://
的可選序列匹配的可選非捕獲組 (?:www\\.)?
一個可選的非捕獲組,匹配www.
的可選序列www.
google\\.
- 一個google.
子 \\S*
- 0+非空白字符。 Python演示 :
import re
test_str = [
"bla bla google.com bla bla", #0
"bla bla www.google.com bla bla", #1
"bla bla api.google.com bla bla", #2
"google.com", #3
"www.google.com", #4
"api.google.com", #5
"http://google.com", #6
"http://www.google.com", #7
"http://api.google.com", #8
"bla bla http://www.google.com bla bla", #9
"bla bla https://www.api.google.com bla bla", #10
"bla bla https://www.map.google.com bla bla" #11
]
r = re.compile(r"(?<!\S)(?:https?://)?(?:www\.)?google\.\S*")
for i,s in enumerate(test_str):
m = r.search(s)
if m:
print("{}\t#{}".format(m.group(0), i))
輸出:
google.com #0
www.google.com #1
google.com #3
www.google.com #4
http://google.com #6
http://www.google.com #7
http://www.google.com #9
如果我的鍵盤工作正常,我會在半小時前回答。
無論如何,我建議不要誇大正則表達式的復雜性。 您可以使用宿主語言來管理黑色(甚至是白色)列表並使用re
模塊輔助。 以下是我在腳本中打包的內容。 顯然,如果必須將此代碼集成到類或函數中,則可能需要進行一些重組:
import re
def main():
input_urls = [
"bla bla google.com bla bla",
"bla bla www.google.com bla bla",
# ...
]
filtered_urls = set()
google_re = re.compile("(\w+\.)?google.com")
blacklist = set(["api."]) # I didn't research enough to remove the dot
for url in input_urls:
# Beware of the difference between match() and search()
# See https://docs.python.org/3/library/re.html#search-vs-match
match = google_re.search(url)
# The second condition will not be evaluated if the first fails
if match is not None and match.group(1) not in blacklist:
filtered_urls.add(url)
print("Accepted URLs:", *filtered_urls, sep="\n\t", end="\n\n")
print("Blacklisted URLs:", *(set(input_urls).difference(filtered_urls)), sep="\n\t")
if __name__ == "__main__":
main()
遺憾的是,由於我的a
和h
鍵盤按鍵不起作用,我無法快速找到刪除網址位置的方法(例如api.google
, www.google
, calendar.google
等)。 我強烈建議這樣做。
我的控制台上顯示的輸出是:
None@vacuum:~$ python3.6 ./filter.py
Accepted URLs:
http://google.com
bla bla google.com bla bla
bla bla www.google.com bla bla
http://www.google.com
google.com
www.google.com
bla bla http://www.google.com bla bla
Blacklisted URLs:
api.google.com
bla bla api.google.com bla bla
http://api.google.com
bla bla https://www.api.google.com bla bla
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.