簡體   English   中英

排除重疊匹配項的正則表達式

[英]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/3foo 5/3 bar3/2016foo 3/2016 bar而不是5/3//3/2016foo 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-101456B/102

示例:Foo [ 1234-101 ]條1234-101

符合條件: 1234-101

使用以下正則表達式:

[^\/0-9a-zA-Z]([0-9a-zA-Z]+[\/.-][0-9a-zA-Z]+)[^\/0-9a-zA-Z]

regexstorm的C#regex測試器的在線演示。

說明

  • 字符類( [...] )表示單個字符,因此量詞{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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM