Разделить строку на предложения с помощью регулярного выражения

Мне нужно сопоставить строку типа «один. Два. Три. Четыре. Пять. Шесть. Семь. Восемь. Девять. Десять. Одиннадцать» на группы по четыре предложения. Мне нужно регулярное выражение, чтобы разбивать строку на группу после каждого четвертого периода. Что-то вроде:

  string regex = @"(.*.\s){4}";

  System.Text.RegularExpressions.Regex exp = new System.Text.RegularExpressions.Regex(regex);

  string result = exp.Replace(toTest, ".\n");

не работает, потому что он заменит текст перед точками, а не только сами точки. Как я могу подсчитать только точки и заменить их точкой и символом новой строки?


person Tai Squared    schedule 28.10.2008    source источник


Ответы (6)


. в регулярном выражении означает "любой символ"

поэтому в вашем регулярном выражении вы использовали .*., которое будет соответствовать слову (это эквивалентно .+)

Вы, вероятно, искали [^.]\*[.] - последовательность символов, которые не являются ".", за которыми следует ".".

person Oliver Hallam    schedule 28.10.2008

Попробуйте определить метод

private string AppendNewLineToMatch(Match match) {
    return match.Value + Environment.NewLine;
}

и используя

string result = exp.Replace(toTest, AppendNewLineToMatch);

Это должно вызывать метод для каждого совпадения и заменять его результатом этого метода. Результатом метода будет совпадающий текст и новая строка.


РЕДАКТИРОВАТЬ: Кроме того, я согласен с Оливером. Правильное определение регулярного выражения должно быть:

  string regex = @"([^.]*[.]\s*){4}";

Другое редактирование: исправлено регулярное выражение, надеюсь, на этот раз я все понял.

person configurator    schedule 28.10.2008
comment
Выражение @ [^.] * [.] \ S * {4} дает ошибку вложенного квантификатора. Выражение @ ([^.] * [.]) {4} \ s *; (от Джеймса Каррана): один. два. три. четыре. один. два. три. четыре. девять. 10. одиннадцать - person Tai Squared; 30.10.2008

Вы вынуждены делать это через регулярное выражение? Не было бы проще просто разделить строку, а затем обработать массив?

person EBGreen    schedule 28.10.2008

Я не уверен, что ответ конфигуратора был искажен редактором или чем-то еще, но он не работает. Правильный шаблон

string regex = @"([^.]*[.]){4}\s*";
person James Curran    schedule 29.10.2008

Выражение поиска: @"(?:([^\.]+?).\s)(?:([^\.]+?).\s)(?:([^\.]+?).\s)(?:([^\.]+?).\s)" Заменить выражение: "$1 $2 $3 $4.\n"

Я запустил это выражение в RegexBuddy с выбранным регулярным выражением .NET, и результат:

one two three four.
five six seven eight.
nine. ten. eleven

Я пробовал использовать тип аранжировки @"(?:([^.]+?).\s){4}", но при захвате будет захвачено только последнее вхождение (то есть слово), поэтому, когда дело доходит до замены, вы потеряете три слова из 4. Пожалуйста, поправьте меня, если я ошибаюсь.

person Ben    schedule 28.10.2008
comment
Исходная строка привела к (скобкам, чтобы показать одну строку [один, два, три.] [Четыре, пять, шесть, семь.] [Восемь. Девять. Десять. Одиннадцать]. Выполнение этого на строке, например: один, два, три, четыре, пять. , шесть, семь, восемь, девять, десять, одиннадцать, привели к [один, два, три] [, четыре, пять, шесть.] - person Tai Squared; 30.10.2008

В этом случае может показаться, что регулярное выражение - это немного излишне. Я бы рекомендовал использовать String.split, а затем разбить полученный массив строк. Это должно быть намного проще и надежнее, чем пытаться заставить регулярное выражение делать то, что вы пытаетесь сделать.

Что-то вроде этого может быть немного легче читать и отлаживать.

String s = "one. two. three. four. five. six. seven. eight. nine. ten. eleven"
String[] splitString = s.split(".")
List li = new ArrayList(splitString.length/2)
for(int i=0;i<splitString.length;i+=4) {
    st = splitString[i]+"."
    st += splitString[i+1]+"."
    st += splitString[i+2]+"."
    st += splitString[i+3]+"."
    li.add(st)
}
person Matthew Brubaker    schedule 28.10.2008