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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
10 063
6

Ответы 6

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

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

и используя

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

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


Обновлено: Кроме того, я согласен с Оливером. Правильное определение регулярного выражения должно быть:

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

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

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

Tai Squared 30.10.2008 00:59

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

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

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

Выражение поиска: @"(?:([^\.]+?).\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. Пожалуйста, поправьте меня, если я ошибаюсь.

Исходная строка привела к (скобкам, показывающим одну строку [один, два, три.] [Четыре, пять, шесть, семь.] [Восемь. Девять. Десять. Одиннадцать]. Выполнение этого на строке типа: «один. Два. Три. Четыре. пять, шесть, семь, восемь, девять, десять, одиннадцать "привели к [один два три.] [четыре пять шесть.]

Tai Squared 30.10.2008 01:05

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

В этом случае может показаться, что регулярное выражение - это немного излишне. Я бы рекомендовал использовать 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)
}

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

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

Другие вопросы по теме