2010-04-07 66 views
7

做任何人都知道一個簡單/乾淨的方式來查找字符串中的子字符串,而忽略一些指定的字符來找到它。我認爲,一個例子可以解釋事情做得更好:查找子字符串忽略指定字符

  • 字符串: 「你好,-this-是一個字符串」
  • 子發現: 「你好這個」
  • 字符忽視: 「」 和 「 - 」
  • 找到子,結果是: 「你好, - 這」

使用正則表達式不是我的要求,但我添加了標籤,因爲它感覺相關。

更新:

爲了使需求更清晰:我需要產生的子被忽略的字符,而不是隻是一個參考給定的子存在。

更新2: 你們當中有些人過分解讀的例子,對不起,我給另一個場景中,應該工作:

  • 字符串:」 A & 3/3/C)412 & 「
  • 子找到: 」A41「
  • 字符忽略:」 &」, 「/」, 「3」, 「C」, 「)」
  • 發現子串,結果是: 「A & 3/3/C)41」

作爲獎勵(本身不是必需的),如果假定子串找到不會有被忽略的字符,它將是很好的,例如:給出我們應該能夠做的最後一個例子:

  • 找到的子串:「A3C412 & 「
  • 字符忽略:」 & 「 」/「, 」3「, 」C「, 」)「
  • 發現子串,結果是:」 A & 3/3/C) 412 &「

對不起,如果我以前不清楚,或者我還沒有:)。

更新3:

謝謝大家誰幫助!,這是我與現在工作的實施:

的下面是一些測試:

我使用了一些自定義擴展方法我不包括,但我相信他們應該是自我解釋性的(我會添加它們,如果你喜歡) 我已經爲執行和測試採納了很多你的想法,但是我給@PierrOz的答案是因爲他是第一批人,並且指出了我的正確方向。 隨時提供建議,作爲關於impl當前狀態的替代解決方案或意見。如果你喜歡。

+0

@Fredy看看我更新的響應,如果我理解正確的,應該包括更新後的場景。 – 2010-04-07 16:14:45

+0

@Fredy - 是否安全地斷定您希望輸入字符串和搜索字符串在搜索之前都乾淨不需要的字符?如果是這樣,下面我提供了一個使用RegEx和字符串搜索的解決方案。 – 2010-04-07 16:51:47

+1

@Ahmad - 我喜歡你的更新,我會從那裏採取一些想法,謝謝。 – 2010-04-07 18:16:53

回答

1
在你的榜樣

,你會怎麼做:

string input = "Hello, -this-, is a string"; 
string ignore = "[-,]*"; 
Regex r = new Regex(string.Format("H{0}e{0}l{0}l{0}o{0} {0}t{0}h{0}i{0}s{0}", ignore)); 
Match m = r.Match(input); 
return m.Success ? m.Value : string.Empty; 

動態,你會建一部分[ - ,]所有的字符忽略,你會插入這部分在你的查詢的所有字符之間。

照顧「 - 」在類[]:把它放在開頭或結尾

所以更一般地,它會看到這樣的:

public string Test(string query, string input, char[] ignorelist) 
{ 
    string ignorePattern = "["; 
    for (int i=0; i<ignoreList.Length; i++) 
    { 
     if (ignoreList[i] == '-') 
     { 
      ignorePattern.Insert(1, "-"); 
     } 
     else 
     { 
      ignorePattern += ignoreList[i]; 
     } 
    } 

    ignorePattern += "]*"; 

    for (int i = 0; i < query.Length; i++) 
    { 
     pattern += query[0] + ignorepattern; 
    } 

    Regex r = new Regex(pattern); 
    Match m = r.Match(input); 
    return m.IsSuccess ? m.Value : string.Empty; 
} 
+0

嗨!,我已經想過這個選項,它絕對適合我。 我一直在尋找更清潔的東西,不需要我建立正則表達式。但如果沒有出現這種情況,你應該得到'回答'。問候。 – 2010-04-07 13:34:48

+0

是的我不確定我們可以避免這樣的事情。此外,在忽略列表中,我們必須照顧「?」等字符。或「+」以及正則表達式語法中使用的所有字符。在測試方法上有一些工作:) – PierrOz 2010-04-07 13:45:57

+0

你是對的,但沒關係,如果這是作爲一個練習留給我:)。如果我以這種方式來實現它,我會盡量記住用更通用的實現或鏈接來更新問題。非常感謝您的幫助。 – 2010-04-07 13:49:51

0

此代碼將做你想做的,但我建議你修改,以更好地滿足您的需求:

string resultString = null; 

try 
{ 
    resultString = Regex.Match(subjectString, "Hello[, -]*this", RegexOptions.IgnoreCase).Value; 
} 
catch (ArgumentException ex) 
{ 
    // Syntax error in the regular expression 
} 
+0

謝謝,但我需要更一般的東西,我的例子只是:) – 2010-04-07 13:37:04

0

你可以用一個正則表達式做到這一點,但它會爲每一個字符後相當乏味你將需要測試零個或多個被忽略的字符。用Regex.Replace(subject, "[-,]", "");去除所有被忽略的字符然後測試子字符串是否存在可能更容易。

或單個正則表達式的方式

Regex.IsMatch(subject, "H[-,]*e[-,]*l[-,]*l[-,]*o[-,]* [-,]*t[-,]*h[-,]*i[-,]*s[-,]*") 
+0

嗨,我想我不能去掉字符,因爲我需要帶有字符的結果子字符串。謝謝! – 2010-04-07 13:36:09

1

編輯:這是一個更新的解決方案,解決您最近更新中的要點。這個想法是一樣的,除非你有一個子字符串,它需要在每個字符之間插入忽略模式。如果子字符串包含空格,它將在空格上分割並在這些字詞之間插入忽略模式。如果您不需要後者的功能(這更符合您的原始問題),那麼您可以刪除提供該模式的Splitif檢查。

請注意,這種方法不會是最有效的。

string input = @"foo ?A&3/3/C)412& bar A341C2"; 
string substring = "A41"; 
string[] ignoredChars = { "&", "/", "3", "C", ")" }; 

// builds up the ignored pattern and ensures a dash char is placed at the end to avoid unintended ranges 
string ignoredPattern = String.Concat("[", 
          String.Join("", ignoredChars.Where(c => c != "-") 
                 .Select(c => Regex.Escape(c)).ToArray()), 
          (ignoredChars.Contains("-") ? "-" : ""), 
          "]*?"); 

string[] substrings = substring.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 

string pattern = ""; 
if (substrings.Length > 1) 
{ 
    pattern = String.Join(ignoredPattern, substrings); 
} 
else 
{ 
    pattern = String.Join(ignoredPattern, substring.Select(c => c.ToString()).ToArray()); 
} 

foreach (Match match in Regex.Matches(input, pattern)) 
{ 
    Console.WriteLine("Index: {0} -- Match: {1}", match.Index, match.Value); 
} 


嘗試這種解決方案出來:

string input = "Hello, -this- is a string"; 
string[] searchStrings = { "Hello", "this" }; 
string pattern = String.Join(@"\W+", searchStrings); 

foreach (Match match in Regex.Matches(input, pattern)) 
{ 
    Console.WriteLine(match.Value); 
} 

\W+將匹配任何非字母數字字符。如果您想自己指定它們,則可以將其替換爲要忽略的字符的字符類別,例如[ ,.-]+(始終將短劃線字符放在開頭或結尾處以避免意外範圍指定)。另外,如果你需要的情況下被忽略使用RegexOptions.IgnoreCase

Regex.Matches(input, pattern, RegexOptions.IgnoreCase) 

如果子是一個完整的字符串的形式,如「你好這個」,你可以很容易地進入了searchString陣列形式這種方式:

string[] searchString = substring.Split(new[] { ' ' }, 
          StringSplitOptions.RemoveEmptyEntries); 
1

這裏有一個非正則表達式的字符串的擴展選項:

public static class StringExtensions 
{ 
    public static bool SubstringSearch(this string s, string value, char[] ignoreChars, out string result) 
    { 
     if (String.IsNullOrEmpty(value)) 
      throw new ArgumentException("Search value cannot be null or empty.", "value"); 

     bool found = false; 
     int matches = 0; 
     int startIndex = -1; 
     int length = 0; 

     for (int i = 0; i < s.Length && !found; i++) 
     { 
      if (startIndex == -1) 
      { 
       if (s[i] == value[0]) 
       { 
        startIndex = i; 
        ++matches; 
        ++length; 
       } 
      } 
      else 
      { 
       if (s[i] == value[matches]) 
       { 
        ++matches; 
        ++length; 
       } 
       else if (ignoreChars != null && ignoreChars.Contains(s[i])) 
       { 
        ++length; 
       } 
       else 
       { 
        startIndex = -1; 
        matches = 0; 
        length = 0; 
       } 
      } 

      found = (matches == value.Length); 
     } 

     if (found) 
     { 
      result = s.Substring(startIndex, length); 
     } 
     else 
     { 
      result = null; 
     } 
     return found; 
    } 
} 
0

這裏有一個非正則表達式的方式使用字符串解析做到這一點。

private string GetSubstring() 

    { 
     string searchString = "Hello, -this- is a string"; 
     string searchStringWithoutUnwantedChars = searchString.Replace(",", "").Replace("-", ""); 

     string desiredString = string.Empty; 
     if(searchStringWithoutUnwantedChars.Contains("Hello this")) 
      desiredString = searchString.Substring(searchString.IndexOf("Hello"), searchString.IndexOf("this") + 4); 

     return desiredString; 
    } 
0

你可以這樣做,因爲大多數這些答案都需要以某種形式重建字符串。

string1爲您的字符串,你想通過

//Create a List(Of string) that contains the ignored characters' 
List<string> ignoredCharacters = new List<string>(); 

//Add all of the characters you wish to ignore in the method you choose 

//Use a function here to get a return 

public bool subStringExist(List<string> ignoredCharacters, string myString, string toMatch) 
{ 
    //Copy Your string to a temp 

    string tempString = myString; 
    bool match = false; 

    //Replace Everything that you don't want 

    foreach (string item in ignoredCharacters) 
    { 
     tempString = tempString.Replace(item, ""); 
    } 

    //Check if your substring exist 
    if (tempString.Contains(toMatch)) 
    { 
     match = true; 
    } 
    return match; 
} 
0

看你總是可以使用正則表達式的組合和字符串搜索

public class RegExpression { 

    public static void Example(string input, string ignore, string find) 
    { 
    string output = string.Format("Input: {1}{0}Ignore: {2}{0}Find: {3}{0}{0}", Environment.NewLine, input, ignore, find); 
    if (SanitizeText(input, ignore).ToString().Contains(SanitizeText(find, ignore))) 
     Console.WriteLine(output + "was matched"); 
    else 
     Console.WriteLine(output + "was NOT matched"); 
    Console.WriteLine(); 
    } 

    public static string SanitizeText(string input, string ignore) 
    { 
    Regex reg = new Regex("[^" + ignore + "]"); 
    StringBuilder newInput = new StringBuilder(); 
    foreach (Match m in reg.Matches(input)) 
    { 
     newInput.Append(m.Value); 
    } 
    return newInput.ToString(); 
    } 

}

用法會像

RegExpression.Example("Hello, -this- is a string", "-,", "Hello this"); //Should match 
RegExpression.Example("Hello, -this- is a string", "-,", "Hello this2"); //Should not match 
RegExpression.Example("?A&3/3/C)412&", "&/3C\\)", "A41"); // Should match 
RegExpression.Example("?A&3/3/C) 412&", "&/3C\\)", "A41"); // Should not match 
RegExpression.Example("?A&3/3/C)412&", "&/3C\\)", "A3C412&"); // Should match 

輸出

輸入:你好,-this-是一個字符串 忽略: - , 查找:你好這個

被匹配

輸入:你好,-this-是一個字符串 忽略: - , 查找:你好this2

是不匹配

輸入:?一個& 3/3/C)412 & 忽略:&/3C) 查找:A41

被匹配

輸入:?甲& 3/3/C)412 & 忽略:&/3C) 查找:A41

是不匹配

輸入:?甲& 3/3/C)412 & 忽略:&/3C ) 查找:A3C412 &

被匹配