Регулярные выражения: совпадение с дополнительным словом - PullRequest
7 голосов
/ 27 августа 2010

Необходимо соответствовать первой части предложения, вплоть до заданного слова. Тем не менее, это слово является необязательным, и в этом случае я хочу соответствовать всему предложению. Например:

У меня есть предложение с предложением, которое я не хочу.

У меня есть предложение, и оно мне нравится.

В первом случае я хочу "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 ]

11 голосов
/ 27 августа 2010

Есть несколько способов сделать это.Вы можете сделать что-то вроде этого:

^(.*?)(with|$)

Первая группа сопоставляется неохотно, т.е. как можно меньше символов.У нас есть общее совпадение, если за этой группой следует либо with, либо конец строки $ якорь .

С учетом этого ввода:

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

Тогда есть два матча (, как видно на rubular.com ):

  • Матч 1:
    • Группа 1: "I have a sentence "
    • Группа 2: "with"
  • Совпадение 2:
    • Группа 1: "I have a sentence and I like it".
    • Группа 2: "" (пустая строка)

Вы можете сделать групповое чередование без захвата с помощью (?:with|$), если вам не нужно различать два случая.

Смежные вопросы

1 голос
/ 27 августа 2010
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"))

Если вам не нужно комплексное сопоставление, предоставляемое регулярным выражением, вы можете использовать комбинацию IndexOf и Remove. (И, очевидно, вы можете абстрагировать логику в вспомогательный метод и / или метод расширения или аналогичный метод):

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));
1 голос
/ 27 августа 2010

Если я правильно понимаю вашу потребность, вы хотите сопоставить либо предложение с точностью до слова «с», либо, если его нет, сопоставить все?Почему бы не написать регулярное выражение для явного поиска двух случаев?

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

Разве это не получит оба случая?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...