2014-09-12 173 views
-3

我是C#的新手,所以我沒有太多經驗。C#查找基於輸入字符串的子字符串

對於一個簡單的體驗項目,我需要從一個類似於我得到的輸入的句子中找到關鍵字。

現在看來解決方案比我想象的要複雜得多,所以請原諒我缺乏經驗或知識。

我從我的數據庫中得到一個字符串,它可以有任意數量的字母,其餘的字符串都是數字,但字符串中的字符總數必須用於匹配。

string ThisIsTheTemplateToLookFor = "AB12345678" 

而且我有一些文本字符串:

string FromThisStringINeedToFind = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s and here comes the text to find AB54925871"; 

隨着ThisIsTheTemplateToLookFor可能是一個正則表達式的命令必須建立查找文本的類似作品。

所以它需要找到:

AB12345678 
AB87654321 
AB67812345 
... 
etc 
... 

正則表達式必須尋找這兩個字母,並從樣本串8個的數字。 或在不同的情況ThisIsTheTemplateToLookFor字符串可以爲A1234正則表達式應該找到A1234A4321A3910

或者蒂姆Schmelter建議也許Levenshtein距離算法

對不起,因爲我的語言不是說英語的本地人

我認爲他的觀點是,搜索字符串在細微方面與尚未枚舉的方式不同,而不是應該找到的字符串。在該示例中,搜索字符串是AB12345678,但應該發現的字符串是AB54925871

我的猜測是,如果搜索字符串是AB12345678,那麼應該找到包含任意順序的10個字符的任何10個字符的子字符串。 - 斧

  • 在第一個例子AB和任何8位數字應該給出結果。
  • 在第二個例子A和任何4個數字應該給出結果。
+0

而不是問一個新的問題,你應該編輯[你的舊](http://stackoverflow.com/questions/25815680/use-a-string-to-find-a-simular-out-of-a -large-string-with-regex),以便它重新打開。 – 2014-09-12 22:04:11

+0

謹慎澄清?我不明白你在問什麼......爲你的程序提供更多的輸入和輸出樣本。 – Andre 2014-09-12 22:04:12

+0

嗨@Tim,我不知道如何,你的迴應已被刪除,所以我有點卡在這裏。 – Giancarlo 2014-09-12 22:05:55

回答

0

由於您已經明確了your first question中的要求,但由於它仍然關閉,我無法發佈答案,因此我會在這裏放置我的兩分錢。

你不需要這樣的正則表達式,下面的工作按需要。您的樣品:

string sample = "AB12345678"; 
string subject = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s and here comes the text to find AB54925871"; 

現在要找到句子中的詞同Length,這與相同的字母開始,並以相同數量的(連續)數字結尾:

string letters = string.Join("", sample.TakeWhile(Char.IsLetter)); 
int countDigits = sample.SkipWhile(Char.IsLetter).TakeWhile(Char.IsDigit).Count(); 

你可以使用這個LINQ查詢:

var matchingWords = subject.Split() // splits by spaces, tabs and new-lines 
    .Where(word => sample.Length == word.Length 
     && letters == string.Join("", word.TakeWhile(Char.IsLetter)) 
     && countDigits == word.SkipWhile(Char.IsLetter).TakeWhile(Char.IsDigit).Count()); 
string word = matchingWords.FirstOrDefault(); // AB54925871 

如果沒有匹配的詞被找到返回null

如果你想找到的所有,並與逗號分隔:

string allWords = string.Join(",", matchingWords); 
+0

非常感謝您的回答,我試過您的解決方案。 它就像一個魅力。 但是我在測試過程中發現了一些新情況: 可能會發現可以找到多個樣本。 我將如何讓「var matchingWords」在由「,」分隔的列表中具有所有命中。 或者我需要爲此創建一個新問題? – Giancarlo 2014-09-13 08:14:59

+0

嗨@Tim,我無法接受你的答案兩次,但非常感謝你,因爲你的回答幫了我很多,以通過這個問題。 – Giancarlo 2014-09-13 10:40:34

0

從您的問題聲明,我們不是在這裏談論火箭科學:只要創建一個這樣的小工廠方法,做什麼你想:

static Regex CreateRegularExpressionFromTemplate(string template) 
{ 
    StringBuilder sb = new StringBuilder() ; 

    foreach(char c in template) 
    { 
    if  (char.IsLetter(  c)) sb.Append(@"\p{L}") ; 
    else if (char.IsNumber(  c)) sb.Append(@"\d" ) ; 
    else if (char.IsWhiteSpace( c)) sb.Append(@"\s" ) ; 
    else if (char.IsPunctuation(c)) sb.Append(@"\p{P}") ; 
    else throw new ArgumentOutOfRangeException("template") ; 
    } 

    string pattern = sb.ToString() ; 
    Regex rx = new Regex(pattern) ; 
    return rx ; 
} 

這將關閉此

@"AB12345678" 

這個

@"\p{L}\p{L}\d\d\d\d\d\d\d\d" 

然後你就可以像

Regex rx = CreateRegularExpressionFromTemplate("AB12345678") ; 
Match m = rx.Match("This is zX98320987 speaking.") ; 

if (m.Success) 
{ 
    Console.WriteLine("We matched '{0}'" , m.Value) ; 
} 
else 
{ 
    Console.WriteLine("no match found") ; 
} 

的東西,並獲得預期

We matched 'zX98320987' 

編輯以注:如果你需要匹配一個字邊界,您可以簡單地添加適當的正面後視和積極的前瞻斷言:

static Regex CreateRegularExpressionFromTemplate(string template) 
{ 
    StringBuilder sb = new StringBuilder() ; 

    sb.Append(@"(?<=(^|\W))") ; // require the match to at the beginning of a word 
    foreach(char c in template) 
    { 
    if  (char.IsLetter(  c)) sb.Append(@"\p{L}") ; 
    else if (char.IsNumber(  c)) sb.Append(@"\d" ) ; 
    else if (char.IsWhiteSpace( c)) sb.Append(@"\s" ) ; 
    else if (char.IsPunctuation(c)) sb.Append(@"\p{P}") ; 
    else throw new ArgumentOutOfRangeException("template") ; 
    } 
    sb.Append(@"(?=($|\W))" ; // require the match to end at the end of a word 

    string pattern = sb.ToString() ; 
    Regex rx = new Regex(pattern) ; 
    return rx ; 
} 
+0

感謝您的回答,但首先匹配的結果不是我需要的結果。 它會有,如果zX98320987是AB98320987 現在,我剛開始學習,我不能監督附加代碼的作用。 但是你用外行人的話來解釋一下? – Giancarlo 2014-09-13 08:19:19