[英]Regular expression for excluding overlapping matches
我正在嘗試在.NET中編寫與客戶端/問題編號匹配的正則表達式。 客戶編號或物料編號由一系列字母或數字組成,客戶編號/物料編號是客戶編號和物料編號的組合,以/
, -
或分隔.
。 例如0204A/101
。
在以下字符串中:
Foo [1234/101] bar 456B / 102 baz
我希望它與[1234-101]
和456B/102
匹配。 為此,我提出了這種模式:
[^a-zA-Z0-9]*([a-zA-Z0-9]+[/\.\-]{1}[a-zA-Z0-9]+)[^a-zA-Z0-9]*
我可以使用捕獲組從每個匹配項中提取客戶/事項編號。
問題是:我想排除日期,以便日期的前兩個部分或最后兩個部分不會被誤解為客戶/事項編號匹配。 舉例來說,如果我有5/3/2016
在我的字符串- “富[1234-101]欄456B / 102巴茲2016年5月3日”,我不想5/3/
為匹配。 為了解決這個問題,我首先嘗試在最終否定范圍的末尾添加/\\.\\-
:
[^a-zA-Z0-9]*([a-zA-Z0-9]+[/\.\-]{1}[a-zA-Z0-9]+)[^a-zA-Z0-9/\.\-]*
但是這沒有用,因為我的量詞*
為零或更大,所以它只將取反的范圍視為發生零次並匹配5/3
。 接下來,我嘗試使它取反范圍出現一次或多次或遇到字符串的結尾:
[^a-zA-Z0-9]*([a-zA-Z0-9]+[/\.\-]{1}[a-zA-Z0-9]+)([^a-zA-Z0-9/\.\-]+|$)
但是,這恰好匹配了/3/2016
,這很有意義。
如何調整模式以匹配一個實例,但在重疊的實例上失敗? 例如,我想以匹配5/3
在foo 5/3 bar
和3/2016
在foo 3/2016 bar
而不是5/3/
或/3/2016
在foo 5/3/2016 bar
。
(?<![\/\-\.a-zA-Z0-9])([a-zA-Z0-9]+[\/\-\.][a-zA-Z0-9]+)(?![\/\-\.a-zA-Z0-9])
可以按您要求的完美工作,請參閱Regex101演示
示例:Foo [
1234-101
]條456B/102
baz 5/3/2016
匹配: 1234-101
和456B/102
示例:Foo [
1234-101
]條1234-101
符合條件: 1234-101
使用以下正則表達式:
[^\/0-9a-zA-Z]([0-9a-zA-Z]+[\/.-][0-9a-zA-Z]+)[^\/0-9a-zA-Z]
說明
字符類( [...]
)表示單個字符,因此量詞{1}
是多余的。
您無需將完整的測試字符串與正則表達式匹配。 如果要這樣做,請使用錨點( ^
, $
)作為分隔符。 就目前而言,當指定了全局匹配時,正則表達式引擎將匹配所有出現的模式。
前導和尾部的斜杠會導致模式不匹配,從而使日期字符串無法顯示。
更新
C#regexen似乎不支持命名字符類,因此從速記還原。
添加了錨點作為目標模式的替代定界符。 因此,測試字符串開頭或結尾的匹配將成功。
環顧四周方法的替代方法是使用error wrong|(right)
形式的消費模式,因此:
\d+\/\d+\/\d+|(\b\w+[-\/\.]\w+\b)
您匹配並吃掉(並忘記)了您不想要的東西\\d+\\/\\d+\\/\\d+
,然后在|
之后的第二部分 ,匹配並記住您想要的內容(\\b\\w+[-\\/\\.]\\w+\\b)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.