检查字符串是不是包含模式,忽略位置。并返回项目匹配的索引
Posted
技术标签:
【中文标题】检查字符串是不是包含模式,忽略位置。并返回项目匹配的索引【英文标题】:Checking if string contains pattern, with places ignored. And returning the index from which the items match检查字符串是否包含模式,忽略位置。并返回项目匹配的索引 【发布时间】:2021-09-18 00:14:54 【问题描述】:我已经实现了这样一个方法:
static void Main(string[] args)
string s = "05 AA 06 15 14";
var pattern1 = "05 AA";
var pattern2 = "06 15";
var pattern3 = "AA ** 15";
var pattern4 = "15 14";
Console.WriteLine(CheckTextContains2(s, pattern1));
Console.WriteLine(CheckTextContains2(s, pattern2));
Console.WriteLine(CheckTextContains2(s, pattern3));
Console.WriteLine(CheckTextContains2(s, pattern4));
private static int CheckTextContains2(string text, string pattern)
if (text.Length < pattern.Length)
return -1;
for (int i = 0; i < text.Length - pattern.Length +1; i++)
for (int j = 0; j < pattern.Length; j++)
if (pattern[j] == '*')
continue;
else if (text[j + i] != pattern[j])
break;
else if (j == pattern.Length -1)
return i;
return -1;
该方法检查给定模式是否在字符串中,但忽略字符“*”并返回起始索引。
但这似乎非常不理想,我可以通过正则表达式获得它吗?
【问题讨论】:
这能回答你的问题吗? Matching strings with wildcard @Sinatr 不,在我的情况下,'*' 只忽略一个字符。我需要知道开始索引。 是的。您可以使用Regex.Match(s, pattern)
来检查位置。 pattern3
的唯一变化是您必须将 *
替换为 .
。 DEMO 查找位置的示例行可能类似于 var posP1 = Regex.Match(s, pattern1) is Success: true m1 ? m1.Index : -1;
@SebastianSchumann:一个很好的答案。太糟糕了,因为您不小心将它发布到评论字段中,OP 将无法接受它......
@Heinzi 这不是偶然作为评论发布的。这是故意的。我希望有人接受这个想法并在其周围添加一些上下文信息。
【参考方案1】:
是的。您可以使用Regex.Match(s, pattern)
来检查位置。 pattern3 的唯一变化是您必须将 *
替换为 .
。
代码可能如下所示:
string s = "05 AA 06 15 14";
var pattern1 = "05 AA";
var pattern2 = "06 15";
var pattern3 = "AA .. 15";
var pattern4 = "15 14";
var posP1 = Regex.Match(s, pattern1) is Success: true m1 ? m1.Index : -1;
var posP2 = Regex.Match(s, pattern2) is Success: true m2 ? m2.Index : -1;
var posP3 = Regex.Match(s, pattern3) is Success: true m3 ? m3.Index : -1;
var posP4 = Regex.Match(s, pattern4) is Success: true m4 ? m4.Index : -1;
Console.WriteLine(posP1);
Console.WriteLine(posP2);
Console.WriteLine(posP3);
Console.WriteLine(posP4);
输出是:
0
6
3
9
DEMO
解释:
正则表达式中的.
是单字符通配符。模式中的所有其他字符都不会影响正则表达式,并将用作要查找的固定文本。对于\[].()*+
之类的字符,您必须小心谨慎。但是,如果您的模式不包含任何这些正则表达式将像 string.IndexOf()
一样工作。
Regex.Match()
方法将返回一个 Match
实例,其中包含必须检查 Success
的属性。示例代码使用模式匹配来完成它,以便能够将其写在一行中。
请记住,您应该使用this._pattern1Finder = new Regex(pattern1, RegexOptions.Compiled)
缓存正则表达式,以避免在每次执行时构造正则表达式。调用看起来像this._pattern1Finder.Match(s) is ...
,而不是使用Regex
的静态方法。这取决于您尝试将相同模式与各种输入匹配的频率。
【讨论】:
【参考方案2】:如果比赛是:越短越好,我想介绍一下:
private static int CheckTextContains(string text, string pattern)
if (text.Length >= pattern.Length)
for (var offset = 0; offset < text.Length - pattern.Length; offset++)
if (!pattern.Where((t, i) => '*' != t && t != text[i + offset]).Any())
return offset;
return -1;
这是一个精简的、可读性和可维护性较差的版本:
private static int CheckTextContains(string text, string pattern)
if (text.Length >= pattern.Length)
for (var offset = 0; offset < text.Length - pattern.Length; offset++)
if (IsMatch(offset))
return offset;
return -1;
bool IsMatch(int offset)
for (var i = 0; i < pattern.Length; i++)
if ('*' != pattern[i] && pattern[i] != text[i+offset]))
return false;
return true;
【讨论】:
以上是关于检查字符串是不是包含模式,忽略位置。并返回项目匹配的索引的主要内容,如果未能解决你的问题,请参考以下文章