Как сопоставить первое слово после выражения с регулярным выражением?
-
23-08-2019 - |
Вопрос
Например, в этом тексте:
Lorem ipsum dolor sit amet, consectetur adipiscing elit.Nunc eu Tellus vel nunc pretium lacinia.Проин сед лорем.Крас sed ipsum.Nunc a libero quis risus sollicitudin imperdiet.
Я хочу сопоставить слово после «ipsum».
Решение
Это похоже на работу по поиску назад, хотя вы должны знать, что не все варианты регулярных выражений поддерживают их.В вашем примере:
(?<=\bipsum\s)(\w+)
Это будет соответствовать любой последовательности букв, которая следует за словом «ipsum» как целым словом, за которым следует пробел.Оно делает нет соответствует самому «ipsum», вам не нужно беспокоиться о его повторной вставке, например, в случаезамены.
Однако, как я уже сказал, некоторые варианты (например, JavaScript) вообще не поддерживают просмотр назад.Многие другие (на самом деле большинство) поддерживают только просмотры назад с «фиксированной шириной», поэтому вы можете использовать этот пример, но не какой-либо из операторов повторения.(Другими словами, (?<=\b\w+\s+)(\w+)
не стал бы работа.)
Другие советы
Некоторые из других респондентов предложили использовать регулярное выражение, которое не зависит от ретроспективного анализа, но я думаю, что для понимания сути необходим полный рабочий пример.Идея состоит в том, что вы сопоставляете всю последовательность («ipsum» плюс следующее слово) обычным способом, а затем используете группу захвата, чтобы изолировать интересующую вас часть.Например:
String s = "Lorem ipsum dolor sit amet, consectetur " +
"adipiscing elit. Nunc eu tellus vel nunc pretium " +
"lacinia. Proin sed lorem. Cras sed ipsum. Nunc " +
"a libero quis risus sollicitudin imperdiet.";
Pattern p = Pattern.compile("ipsum\\W+(\\w+)");
Matcher m = p.matcher(s);
while (m.find())
{
System.out.println(m.group(1));
}
Обратите внимание, что при этом печатаются как «dolor», так и «Nunc».Чтобы сделать это с помощью ретроспективной версии, вам придется сделать что-то хакерское, например:
Pattern p = Pattern.compile("(?<=ipsum\\W{1,2})(\\w+)");
Это в Java, который требует, чтобы просмотр назад имел очевидную максимальную длину.Некоторые варианты не обладают даже такой гибкостью, а некоторые вообще не поддерживают просмотр назад.
Однако самая большая проблема, с которой люди сталкиваются в своих примерах, связана не с просмотром назад, а с границами слов.И Дэвид Кемп, и ck, похоже, ожидают \b
чтобы соответствовать пробелу после 'm', но это не так;он соответствует положению (или границе) между «м» и пробел.
Это распространенная ошибка, которую я даже видел повторенной в нескольких книгах и учебных пособиях, но конструкция границы слова, \b
, никогда не соответствует никаким символам.Это утверждение нулевой ширины, как обходные пути и привязки (^
, $
, \z
, и т. д.), и ему соответствует позиция, которой либо предшествует словесный символ и за ним не следует ни один, либо за которым следует словесный символ и которому не предшествует ни один.
ипсум\b(\w*)
С javascript
вы можете использовать (?=ipsum.*?(\w+))
Это также получит второе вхождение (Nunc)
ipsum\b(.*)\b
РЕДАКТИРОВАТЬ:хотя в зависимости от вашей реализации регулярного выражения это может быть голодным и найти все слова после ipsum