簡體   English   中英

string.IndexOf 搜索全詞匹配

[英]string.IndexOf search for whole word match

我正在尋找一種方法來搜索字符串以進行完全匹配或全字匹配。 RegEx.MatchRegEx.IsMatch似乎沒有讓我到達我想去的地方。
考慮以下場景:

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "SUBTOTAL 34.37 TAX TOTAL 37.43";
            int indx = str.IndexOf("TOTAL");
            string amount = str.Substring(indx + "TOTAL".Length, 10);
            string strAmount = Regex.Replace(amount, "[^.0-9]", "");

            Console.WriteLine(strAmount);
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    }
}

上面代碼的輸出是:

// 34.37
// Press any key to continue...

問題是,我不想要SUBTOTAL ,但IndexOf找到單詞TOTAL的第一次出現,它在SUBTOTAL ,然后產生錯誤的 34.37 值。

所以問題是,是否有一種方法可以強制IndexOf僅查找完全匹配,或者是否有另一種方法可以強制完全匹配整個單詞,以便我可以找到該完全匹配的索引,然后使用它執行一些有用的功能。 據我所知, RegEx.IsMatchRegEx.Match只是boolean搜索。 在這種情況下,僅僅知道存在精確匹配是不夠的。 我需要知道它在字符串中的位置。

任何意見,將不勝感激。

您可以使用正則表達式

string str = "SUBTOTAL 34.37 TAX TOTAL 37.43";
var indx = Regex.Match(str, @"\WTOTAL\W").Index; // will be 18

我的方法比接受的答案更快,因為它不使用正則表達式。

string str = "SUBTOTAL 34.37 TAX TOTAL 37.43";
var indx = str.IndexOfWholeWord("TOTAL");

public static int IndexOfWholeWord(this string str, string word)
{
    for (int j = 0; j < str.Length && 
        (j = str.IndexOf(word, j, StringComparison.Ordinal)) >= 0; j++)
        if ((j == 0 || !char.IsLetterOrDigit(str, j - 1)) && 
            (j + word.Length == str.Length || !char.IsLetterOrDigit(str, j + word.Length)))
            return j;
    return -1;
}

您可以使用單詞邊界\\bMatch.Index屬性

var text = "SUBTOTAL 34.37 TAX TOTAL 37.43";
var idx = Regex.Match(text, @"\bTOTAL\b").Index;
// => 19

請參閱C# 演示

\\bTOTAL\\b沒有用任何其他字母、數字或下划線括起來時,它匹配TOTAL

如果您需要將一個單詞作為一個完整的單詞來計算(如果它用下划線括起來),請使用

var idx = Regex.Match(text, @"(?<![^\W_])TOTAL(?![^\W_])").Index;

其中(?<![^\\W_])是負向后視,如果存在非單詞以外的字符並立即在當前位置的左側下划線,則匹配失敗(因此,可以有字符串的開頭位置,或一個既不是數字也不是字母的字符),並且(?![^\\W_])是一個類似的負前瞻,僅當存在字符串位置的結尾或字符而不是字母或數字時才匹配就在當前位置的右側。

如果邊界是空格或字符串的開始/結束使用

var idx = Regex.Match(text, @"(?<!\S)TOTAL(?!\S)").Index;

其中(?<!\\S)要求緊靠左邊的字符串開頭或空格,而(?!\\S)要求字符串結尾或右邊的空格。

注意\\b , (?<!...)(?!...) 是非消耗模式,即匹配這些模式時正則表達式索引不會前進,因此,您可以獲得單詞的確切位置你搜索。

為了使接受的答案更安全(因為IndexOf返回 -1 表示不匹配):

string pattern = String.Format(@"\b{0}\b", findTxt);
Match mtc = Regex.Match(queryTxt, pattern);
if (mtc.Success)
{
    return mtc.Index;
}
else
    return -1;

雖然這可能是僅適用於您的示例的黑客,但請嘗試

string amount = str.Substring(indx + " TOTAL".Length, 10);

在總數之前給一個額外的空間。 由於SUBTOTAL不會發生這種情況,因此它應該跳過您不想要的詞,只查找一個孤立的TOTAL

我也推薦 LB 的 Regex 解決方案,但如果您不能使用 Regex,那么您可以使用 String.LastIndexOf("TOTAL")。 假設 TOTAL 總是在 SUBTOTAL 之后?

http://msdn.microsoft.com/en-us/library/system.string.lastindexof(v=vs.110).aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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