正则表达式:匹配可选单词

时间:2010-08-27 16:33:50

标签: c# regex

需要匹配句子的第一部分,直到给定的单词。但是,该单词是可选的,在这种情况下,我想匹配整个句子。例如:

  

我有一句话,附有我不想要的条款。

     

我有一句话,我喜欢它。

在第一种情况下,我想要"I have a sentence"。在第二种情况下,我想要"I have a sentence and I like it."

Lookarounds将给我第一个案例,但是一旦我尝试使其成为可选项,为了涵盖第二个案例,我得到了整个第一句话。我试过让表达懒惰......没有骰子。

适用于第一种情况的代码:

var regEx = new Regex(@".*(?=with)");
string matchstr = @"I have a sentence with a clause I don't want";

if (regEx.IsMatch(matchstr)) {
    Console.WriteLine(regEx.Match(matchstr).Captures[0].Value);
    Console.WriteLine("Matched!");
}
else {
    Console.WriteLine("Not Matched : (");
}

我希望的表达方式:

var regEx = new Regex(@".*(?=with)?");


有什么建议吗?

提前致谢!
詹姆斯

3 个答案:

答案 0 :(得分:11)

有几种方法可以做到这一点。你可以这样做:

^(.*?)(with|$)

第一组不情愿地匹配,即尽可能少的字符。如果此论坛后跟with或行尾$ anchor,我们会进行整体匹配。

鉴于此输入:

I have a sentence with a clause I don't want.
I have a sentence and I like it.

然后有两个匹配(as seen on rubular.com):

  • 第1场比赛:
    • 第1组:"I have a sentence "
    • 第2组:"with"
  • 第2场比赛:
    • 第1组:"I have a sentence and I like it"
    • 第2组:""(空字符串)

如果您不需要区分这两种情况,则可以使用(?:with|$)使分组交替不捕获。

相关问题

答案 1 :(得分:1)

如果我理解你的需要,你想要将句子与'with'一词匹配,或者,如果它不存在,则匹配整个事物?为什么不编写正则表达式来明确查找这两种情况?

/(.*) with |(.*)/

这不会导致这两种情况吗?

答案 2 :(得分:1)

string optional = "with a clause I don't want" 
string rx = "^(.*?)" + Regex.Escape(optional) + ".*$";

// displays "I have a sentence"
string foo = "I have a sentence with a clause I don't want.";
Console.WriteLine(Regex.Replace(foo, rx, "$1"));

// displays "I have a sentence and I like it."
string bar = "I have a sentence and I like it.";
Console.WriteLine(Regex.Replace(bar, rx, "$1"))

如果您不需要正则表达式提供的复杂匹配,则可以使用IndexOfRemove的组合。 (显然,您可以将逻辑抽象为辅助和/或扩展方法或类似方法):

string optional = "with a clause I don't want" 

// displays "I have a sentence"
string foo = "I have a sentence with a clause I don't want.";
int idxFoo = foo.IndexOf(optional);
Console.WriteLine(idxFoo < 0 ? foo : foo.Remove(idxFoo));

// displays "I have a sentence and I like it."
string bar = "I have a sentence and I like it.";
int idxBar = bar.IndexOf(optional);
Console.WriteLine(idxBar < 0 ? bar : bar.Remove(idxBar));