一串搜索全词匹配的索引

本文关键字:索引 搜索 一串 | 更新日期: 2023-09-27 18:10:29

我正在寻找一种在字符串中搜索完全匹配或全词匹配的方法。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搜索。在这种情况下,仅仅知道完全匹配是不够的。我需要知道它在字符串中的位置。

如有任何建议,我们将不胜感激。

一串搜索全词匹配的索引

您可以使用Regex

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

我的方法比接受的答案更快,因为它不使用Regex。

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_])是一个负查找,如果在当前位置的左侧紧邻非单词和下划线以外的字符(因此,可以有字符串位置的开头,或者不是数字或字母的字符(,并且CCD_ 16是仅在紧邻当前位置的右侧存在字符串末尾位置或除字母或数字之外的字符的情况下匹配的类似的负前瞻。

如果边界是空白或字符串的开始/结束,请使用

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

我也推荐L.B.的Regex解决方案,但如果你不能使用Regex,那么你可以使用String.LastIndexOf("TOTAL"(。假设TOTAL总是在SUBTOTAL之后?

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