2009-08-11 47 views
6

我想測試一個正則表達式是否匹配特定索引處的字符串的一部分(並且只從該特定索引處開始)。例如,給定字符串「one two 3 4 five」,我想知道,在索引8處,正則表達式[0-9] +將匹配「3」。 RegularExpression.IsMatch和Match都需要一個起始索引,但是如果需要的話,它們都會搜索整個字符串的其餘部分進行匹配。c#正則表達式匹配字符串中的特定索引?

string text="one two 3 4 five"; 
Regex num=new Regex("[0-9]+"); 

//unfortunately num.IsMatch(text,0) also finds a match and returns true 
Console.WriteLine("{0} {1}",num.IsMatch(text, 8),num.IsMatch(text,0)); 

很顯然,我可以檢查所產生的比賽開始,我感興趣的是指數,但我將在做大量的大串倍,所以我不想把時間浪費在搜索對於稍後在字符串中的匹配。另外,我不會提前知道我將實際測試的字符串是什麼正則表達式。

我不想:

  1. 因爲在我 情況在一些邊界 像空格分割字符串我不會提前知道 什麼合適的邊界將是
  2. 有修改輸入字符串中 任何方式(如獲得子 在索引8,然後在正則表達式 使用^)
  3. 查詢的 串的其餘部分的墊ch或者做任何事情 否則不會對 執行大量針對 大字符串的測試。

我想解析一個潛在的大型用戶提供的正文使用任意用戶提供的語法。語法將以BNF或PEG類似的語法定義,並且終端將是字符串文字或正則表達式。因此,我需要檢查字符串的下一部分是否與由語法驅動的潛在終端相匹配。

+1

你能解釋一下你在廣義上想要做什麼嗎?你對你不想做的事情的限制令人困惑。 – 2009-08-11 20:34:48

+0

我添加了關於我在做什麼的簡要描述。此外,這些要求真的可以歸結爲:我不想做任何慢的事情,我也沒有深入瞭解我想要解決的問題。 – Rngbus 2009-08-11 23:34:22

回答

11

如何使用Regex.IsMatch(string, int)使用以\G開頭的正則表達式(意思是「上次匹配的開始」)?這似乎

工作:

using System; 
using System.Text.RegularExpressions; 

class Test 
{ 
    static void Main() 
    { 
     string text="one two 3 4 five"; 
     Regex num=new Regex(@"\G[0-9]+"); 

     Console.WriteLine("{0} {1}", 
          num.IsMatch(text, 8), // True 
          num.IsMatch(text, 0)); // False 
    } 
} 
+0

有趣的是,如果有人工設置最後一個匹配位置的方法,那麼這可能會解決。否則我不認爲這會有幫助,因爲我會在不同的正則表達式和不同的位置之間跳躍。 – Rngbus 2009-08-12 00:13:38

+0

我有機會嘗試一下,它似乎正是我想要的。它將傳遞的起始索引視爲「最後一場比賽的開始」,而不管最後一場比賽的實際位置。很好,謝謝! – Rngbus 2009-08-12 00:33:59

+2

只是爲了給其他任何有這個問題的人添加一些信息,http://www.regular-expressions.info/continue.html描述了\ G錨。這看起來意味着「開始最後一場比賽」或「開始比賽嘗試」,具體取決於實施情況。在某些實現中,它可能不會解決這個問題,但它似乎是C#中「匹配嘗試的開始」,並且很適合在特定位置進行匹配。 – Rngbus 2009-08-12 00:43:42

2

如果你只想要搜索的文本字符串,搶的正則表達式之前子。

myRegex.Match(myString.Substring(8, 10)); 
+2

請參閱問題中的第2點。 – 2009-08-11 20:11:51

+0

看起來不像這樣修改了輸入字符串,所以+1。如果第二點不僅僅是改變輸入字符串,它需要被編輯。 – ojrac 2009-08-11 20:17:44

+1

好吧,它將輸入*修改爲正則表達式*。鑑於「在大型字符串上執行大量這樣的操作」,我不會認爲子字符串是理想的解決方案。 – 2009-08-11 20:25:55

1

我不知道我完全理解這個問題,但在我看來,你可以簡單地讓正則表達式,例如位置部分

^.{8}[\d] 

如果字符串的開頭和數字之間有8個字符,它們將匹配。

+1

這並不理想,因爲它會涉及修改我想測試的每個位置的正則表達式。這也將取決於正則表達式足夠聰明,以便將^。{8}優化爲立即跳轉到位置8的東西。 – Rngbus 2009-08-11 23:19:19

0

如果您知道字符串中潛在匹配的最大長度,則檢查此字符串是否會限制字符串的掃描。

如果你只是檢查數字,這可能比檢查任意表達式更容易。正則表達式的本質是掃描直到結束才能找到匹配。如果你想防止掃描你需要包括一個長度,或使用正則表達式以外的東西。

string text = "one two 3 4 five"; 
Regex num = new Regex("[0-9]+"); 
int indexToCheck = 8; 
int maxMatchLength = ...; 
Match m = num.Match(text, indexToCheck, maxMatchLength); 

你知道什麼類型的表達式可能針對字符串運行,並且會掃描整個字符串是否有太多開銷?

num.Match將返回第一個命中(如果存在),然後停止掃描。如果你想要更多的匹配,你可以調用m.NextMatch()來繼續掃描匹配。

+0

不幸的是,我不知道正則表達式會事先提供什麼,並且不能提供除休息以外的最大長度的字符串。 – Rngbus 2009-08-11 23:21:16

+0

查找的表達式可以具有變化的長度,這取決於空白,例如,新行和縮進段落開始,或其他。 – ProfK 2016-11-03 10:21:44