匹配与空白末尾/行首

问题描述:

我无法弄清楚如何获得一个C#正则表达式IsMatch匹配<keyword>后跟行结束或空白。与<keyword>匹配<keyword>与空白末尾/行首

我目前有[\s]+keyword[\s]+,它适用于空格,但不适用于keyword<end of string><start of string>keyword

我试过[\s^]+keyword[\s$]+,但这使它无法与空格匹配,并且不能在字符串的末尾或开始处工作。

这是我试过的代码:

string pattern = string.Format("[\\s^]+{0}[\\s$]+",keyword); 
if(Regex.IsMatch(Text, pattern, RegexOptions.IgnoreCase)) 
+0

你可以给一个样本输入和输出? – 2013-04-25 11:13:49

+0

正确的例子如果关键字 输入是'这是正确的''这是正确的''正确''正确'也正确' 错误'fdcorrect''correctdfdfd' – f1wade 2013-04-25 11:41:33

的问题是,^$内字符类不作为锚,但作为文字字符处理。你可以简单地使用轮换,而不是一个字符类:

string pattern = string.Format(@"(?:\s|^){0}(?:\s|$)",keyword); 

注意,没有必要为+,因为你只是想知道是否有一个空间。你不在乎是否有更多。 ?:只是良好的做法,并抑制capturing,你不需要在这里。并且@使字符串成为一个逐字字符串,您不必在其中双重转义您的反斜杠。

还有另一种方式,我觉得稍微整洁。您可以使用lookarounds,以确保您的关键字左侧和右侧没有非空格字符(是的,双重否定,请仔细考虑)。这个假设是有效的,如果有一个空格字符或者如果字符串的一端:

string pattern = string.Format(@"(?<!\S){0}(?!\S)",keyword); 

这并不完全一样,但可能会略微高效(你必须配置文件是确实如此 - 如果它甚至重要)。

您也可以使用第一图案(与非逻辑反相)与(正)lookarounds:

string pattern = string.Format(@"(?<=\s|^){0}(?=\s|$)",keyword); 

然而,这并不能真正有所作为的第一图案,除非你想在字符串中找到多个匹配项。

顺便说一句,如果你的keyword可能包含正则表达式元字符(如|$+等),请务必先使用Regex.Escape

+0

会使您的前瞻/后面匹配成功。 – f1wade 2013-04-25 11:32:08

+0

@ f1wade我不确定你的意思。它只是满足你的规范 - 它匹配'关键字',如果它立即被空格或字符串的末尾所包围。它也可以处理较长的字符串,其中'keyword'只是其中一个单词。 – 2013-04-25 11:34:08

+0

正如你使用\ S而不是\大写版本匹配非空白我想? – f1wade 2013-04-25 11:40:25

试试这个:

string pattern = string.Format("^\\s*{0}\\s*$",keyword); 
+1

我不认为这将允许其他词在行首和关键字之间。同样,如果前面和后面都有非空白字符,并且如果关键字不在那里,那么行末 – f1wade 2013-04-25 11:25:59

逃吧,我发现这个其他职位 How to specify "Space or end of string" and "space or start of string"?

,并在回答这一问题 所以我的代码现在

string pattern = string.Format("\\b+{0}\\b+",keyword); 
if(Regex.IsMatch(UserText, pattern, RegexOptions.IgnoreCase)) 
+2

您不应该认为'+'是完全不必要的。 '\ b'不匹配一个字符,而是一个位置,所以它不会提前引擎的“光标”。因此'\ b'和'\ b \ b \ b'完全一样。而且,如果它出现像'some string:keyword.',这将匹配你的关键字,因为'\ b'匹配单词字符('[a-zA-Z0-9_]'...在.NET中可能有更多的Unicode字符)和非单词字符。如果你真的想限制它的空间,看看我的答案。 – 2013-04-25 11:30:13

+0

so \ b匹配任何非字符,即不是[a-zA-Z0-9_]? – f1wade 2013-04-25 11:38:51

+1

我的观点是,[它根本不匹配任何字符,它匹配一个位置。](http://www.regular-expressions.info/wordboundaries.html)。例如,如果你的输入字符串是'a-c'(其中'-'是一个非单词字符),那么模式'\ ba \ b'将只匹配** a。 '-'不是匹配的一部分,因为'\ b'只是检查两个相邻字符的位置,而不实际将它们包含在匹配中。这也意味着在这个例子中'a \ b-'(这是一个毫无意义的模式)会给你一个匹配。 – 2013-04-25 11:44:25

我不完全相信你真的想用这个正则表达式来完成,但下面的代码将匹配字符串“关键字”时,它在它的两边空白:

string resultString = null; 
try { 
    Regex regexObj = new Regex(@"\b(keyword)\b"); 
    resultString = regexObj.Match(subjectString).Value; 
} catch (ArgumentException ex) { 
    // Syntax error in the regular expression 
} 

一般可以解释如:\ b断言开始和结束字边界的位置。在这种情况下,我假定感兴趣的词是关键词。

我还从我对你的问题的解释中想到,你可能有兴趣将关键字后面的整个系列字符匹配到换行符。如果是这样的情况下,下面的正则表达式的代码将返回匹配:

string resultString = null; 
try { 
    Regex regexObj = new Regex(@"\bkeyword\b(\w*\s*)$"); 
    resultString = regexObj.Match(subjectString).Value; 
} catch (ArgumentException ex) { 
    // Syntax error in the regular expression 
} 

这个正则表达式可以解释为寻找开始和结束字边界这是两边的\ b中的原因。 (\ w * \ s *)$读取像这样匹配所有字\ w字符和空格字符\ s *的次数,并将位置移动到行的末尾$。

该下一位代码将读取包含关键字的整行数据,不包含关键字的数据行将不匹配。

string resultString = null; 
try { 
    Regex regexObj = new Regex("^.*keyword.*$"); 
    resultString = regexObj.Match(subjectString).Value; 
} catch (ArgumentException ex) { 
    // Syntax error in the regular expression 
} 

解释的:^位置在字符串的开始,*匹配这不是一个换行符,关键字是遂把其次是任何字符*所以剩余的非换行字符。被包括在内,并且$在该字符串的末尾处声明该位置,该位置将是本示例中的整个行。

我希望以上内容有用,如果不是这一次,也许在未来。我总是试图找到替代做法来达到同样的结果,所以如果你有任何建设性的批评,请发布。

最好的祝福, 史蒂夫