[英]conditional regex on multiline string in python
這個問題類似於我原來的帖子。
發布另一個新問題的原因是這里的要求與原來的要求有點不同。
如果給定的字符串是逐行的,那么原始答案就足夠了。 但是,那里的答案不能涵蓋多行字符串的情況。 見下文
測試用例 | 測試字符串 | 期望來自 bool(re.match(...)) 的值 |
---|---|---|
1. 天真的比賽 | xxxx |
真的 |
2.錯誤的model名字 | xxxx |
錯誤的 |
3.缺少model | xxxx |
真的 |
我嘗試多個正則表達式。 但是,它們都在任一測試用例 (2) / (3) 上都失敗了。
試過正則表達式 | 測試失敗 |
---|---|
(board add 0/1)? (?(1) (aaa|bbb)) |
2個 |
^(?:(?.board add 0/1)?)*$|board add 0/1 (::aaa|bbb) |
2個 |
board add 0/1 (aaa|bbb) |
3個 |
(?=board add 0/1 )(?:board add 0/1 (aaa|bbb)) |
3個 |
是否可以編寫一個正則表達式來獲得上述測試用例通過?
您可以通過以下url查看它們
https://regex101.com/r/2l2Qd4/1
筆記:
board add 0/1
而不是board add 0/\d+
board add 0/1
的特定正則表達式。 然后,我可以將正則表達式擴展到board add 0/2
到board add 0/21
一個接一個board add 0/1
存在於字符串中,則它后面必須跟有(aaa|bbb)
。 否則無效board add 0/1
,則這是一個有效字符串。在這種情況下,您可以使用此正則表達式
board add 0/\d+ (?!aaa|bbb)
如果正則表達式匹配,則該字符串無效。
import re
strings = [
"""xxxx
xxxx
board add 0/1 aaa
board add 0/2 aaa
board add 0/3 bbb
board add 0/4 bbb
board add 0/5 aaa
#""",
"""xxxx
xxxx
board add 0/1 xxx
board add 0/2 aaa
board add 0/3 bbb
board add 0/4 aaa
board add 0/5 bbb
#""",
"""xxxx
xxxx
board add 0/2 aaa
board add 0/3 bbb
board add 0/4 bbb
board add 0/5 aaa
#"""
]
for string in strings:
print(not bool(re.search(r"board add 0/\d+ (?!aaa|bbb)", string)))
True
False
True
re.search
按給定模式返回匹配的字符串塊。 如果不存在任何匹配項,則返回None
。 該解決方案基於否定有效字符串。 因此,如果在board add 0/1
之后既沒有跟隨aaa
也沒有跟隨bbb
,則該字符串無效。 rest 按照您在上一個問題中的描述傳遞。 因此,如果re.search
返回None
以外的任何值,則not bool(...)
會將值轉換為預期結果。
注意:我使用的not bool(...)
,因為如果字符串不包含模式,則它是有效的。
在這個問題中,我們可以只關注 board add 0/1 而忽略其他 board add 0/x 。 事實上,盡管有否定,但您當前的解決方案符合我的需要。 我只是想知道為什么我們需要否定,為什么我的回答不起作用。
第一個(board add 0/1)? (?(1) (aaa|bbb))
(board add 0/1)? (?(1) (aaa|bbb))
我不明白你期望匹配什么。 第二個正則表達式類似於我對您上一個問題的回答。 第三個更接近答案。
我更改了我建議您之前的問題的正則表達式。
^(?:(?!board add 0\/1).)*$|^.*?board add 0\/1 (?:aaa|bbb).*$
現在您可以使用re.match
而不是re.search
...
for string in strings:
print(bool(re.match(r"^(?:(?!board add 0\/1).)*$|^.*?board add 0\/1 (?:aaa|bbb).*$", string, re.S)))
True
False
True
注意:還使用了re.S
(單行)標志。
您似乎想要匹配所有以 aaa 或 bbb 結尾的板行,並在以非空白字符開頭的字符串之間縮進。
為防止部分匹配,您需要識別重復板部分之前和之后的部分。
^\S.*(?:\n[^\S\n]+board add 0/\d+ (?:aaa|bbb))+\n\S
解釋
^
字符串開始\S.*
匹配一個非空白字符和該行的 rest(?:
非捕獲組作為一個整體重復
\n[^\S\n]+
匹配換行符后跟 1+ 個空格board add 0/\d+ (?:aaa|bbb)
匹配\d+
匹配 1+ 數字的棋盤模式)+
關閉非捕獲組,重復1+次至少匹配一行\n\S
匹配換行符和非空白字符
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.