我有以下字符串:正則表達式:關於貪婪,懶惰和子串
123322
從理論上講,正則表達式1.*2
應符合以下幾點:
12
(因爲*
可以是零字符)12332
123322
如果我使用正則表達式1.*2
它匹配123322
。
使用1.*?2
,它將匹配12
。
有沒有辦法匹配12332
呢?
完美的東西會得到所有可能matchess字符串中(無論一個匹配的子串的另一)
我有以下字符串:正則表達式:關於貪婪,懶惰和子串
123322
從理論上講,正則表達式1.*2
應符合以下幾點:
12
(因爲*
可以是零字符)12332
123322
如果我使用正則表達式1.*2
它匹配123322
。
使用1.*?2
,它將匹配12
。
有沒有辦法匹配12332
呢?
完美的東西會得到所有可能matchess字符串中(無論一個匹配的子串的另一)
你是對的。不知道爲什麼我沒有想到它。我將與第1組中的捕獲物相匹配;) – 2011-03-04 22:22:39
您將需要一個單獨的表達式爲每個個案,這取決於你想匹配三三兩兩的數量:
1(.*?2){1} #same as 1.*?2
1(.*?2){2}
1(.*?2){3}
...
好主意。一個簡單的循環就足夠了,從1 util開始,它找不到匹配;) – 2011-03-02 07:12:13
現在我看到@Kobi的答案,只有每個匹配都是獨立的(例如:'12331232':'1(。*?2) {2}'應該匹配'123312'和'1232',但是它們中有一個共同的字符串:'12')。當然,這與generl中的常規表達式有關,而與您的答案無關;) – 2011-03-02 07:39:20
一般情況下,這是不可能的。正則表達式匹配引擎並不是真正用於查找重疊匹配的。一個快速的解決方案是簡單地檢查手動所有子模式:
string text = "1123322";
for (int start = 0; start < text.Length - 1; start++)
{
for (int length = 0; length <= text.Length - start; length++)
{
string subString = text.Substring(start, length);
if (Regex.IsMatch(subString, "^1.*2$"))
Console.WriteLine("{0}-{1}: {2}", start, start + length, subString);
}
}
現在,是有可能得到一個整體的正則表達式的解決方案?大多數情況下,答案是否定的。然而,.Net確實有一些技巧可以幫助我們:它允許可變長度的後視,並允許每個捕獲組記憶所有捕獲(大多數引擎只返回每個組的最後一個匹配)。濫用這些,我們可以模擬正則表達式引擎中的一樣for
循環:
string text = "1123322!";
string allMatchesPattern = @"
(?<=^ # Starting at the local end position, look all the way to the back
(
(?=(?<Here>1.*2\G))? # on each position from the start until here (\G),
. # *try* to match our pattern and capture it,
)* # but advance even if you fail to match it.
)
";
MatchCollection matches = Regex.Matches(text, allMatchesPattern,
RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);
foreach (Match endPosition in matches)
{
foreach (Capture startPosition in endPosition.Groups["Here"].Captures)
{
Console.WriteLine("{0}-{1}: {2}", startPosition.Index,
endPosition.Index - 1, startPosition.Value);
}
}
注意,目前有一個小錯誤在那裏 - 發動機不嘗試匹配的最後結局位置($),這樣你就鬆幾場比賽。目前,在字符串末尾添加!
可解決該問題。
這也是有效的。實際上,這與我在應用程序的另一部分中所做的非常相似,但問題在於它是'O(n^2 * m)'('m':'Regex.IsMatch'的代價) 。 'm'應該是'O(n)',因爲它是自動化的。 '1123322'沒有問題,但是從文件中提取的文本可能有點大,而且效率不高,但是如果客戶端請求它,我仍然需要做些什麼:/ – 2011-03-02 07:45:55
@Oscar - 我說過,我不明白如何避免高複雜度,假設正則表達式比你描述的更復雜。你可以做一些特定於你的正則表達式來優化它,但是在更糟糕的情況下,你會創建[所有可能的子串](http://ideone.com/rH5dd),所以你可以重複它們:它沒有什麼區別,複雜性明智,如果這是你的代碼或正則表達式引擎。 (另外,我把你的問題弄錯了*理論*問題,而不是實際的問題,我認爲我不會給我的客戶端那個正則表達式':)') – Kobi 2011-03-02 08:18:14
你確定1。*?2匹配123322嗎?我會認爲它只匹配12. – Duniyadnd 2011-03-02 05:59:25
@Duniyadnd你說得對。我修好了它。 – 2011-03-02 06:01:42
如果你在字符串中多次使用'1',該怎麼辦?如果你想要一個簡單的'1. * 2'模式,你可以簡單地找到'1'的所有位置和'2'的所有位置,並選擇一個比另一個大的位置 - 沒有理由在正則表達式中那種情況。我的答案對問題有更爲一般的解決方法,但我可能已經過分複雜。 :) – Kobi 2011-03-02 07:17:05