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

Например, в этом тексте:

Lorem ipsum dolor sit amet, conctetur adipiscing elit. Nunc eu tellus vel nunc pretium lacinia. Proin sed lorem. Cras sed ipsum. Nunc a libero quis risus sollicitudin imperdiet.

Я хочу сопоставить слово после «ipsum».


person Matthew Taylor    schedule 13.02.2009    source источник


Ответы (6)


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

(?<=\bipsum\s)(\w+)

Это будет соответствовать любой последовательности буквенных символов, следующих за «ipsum» как целое слово, за которым следует пробел. Он не соответствует самому "ipsum", вам не нужно беспокоиться о его повторной вставке в случае, например, замены.

Однако, как я уже сказал, некоторые разновидности (например, JavaScript) вообще не поддерживают ретроспективный просмотр. Многие другие (фактически большинство) поддерживают только просмотр назад с фиксированной шириной, поэтому вы можете использовать этот пример, но не любой из операторов повторения. (Другими словами, (?<=\b\w+\s+)(\w+) не будет работать.)

person Ben Blank    schedule 13.02.2009
comment
Однако, когда дело доходит до использования подстановочных знаков, ретроспективный просмотр имеет тенденцию быть довольно ограниченным. - person cletus; 13.02.2009
comment
Возможно, здесь даже нет необходимости в ретроспективе. В зависимости от того, что означает «Я хочу сопоставить» в вопросе, см. Решение Дэвида Кемпа. - person user55400; 13.02.2009
comment
нулевая ширина - это то, что вам нужно, просто группировка - это банальный выход из тюрьмы. - person annakata; 13.02.2009
comment
Фиксированная ширина - термин, вводящий в заблуждение - это больше максимальная ширина, да? В большинстве случаев можно использовать подходящий предел, например: (? ‹= \ B \ w {1,100} \ s {1,100}) - person Peter Boughton; 13.02.2009
comment
@Peter - Нет, это действительно фиксированная ширина. Попробуйте там свое регулярное выражение в Python; это вызывает исключение. - person Ben Blank; 14.02.2009
comment
Я думаю, что нашел способ обойти ограничение фиксированной ширины просмотра назад в некоторых разновидностях регулярных выражений в некоторых случаях. Скажем, вы хотите найти B, но только если перед ним нет A и любого количества пробелов. В большинстве разновидностей регулярных выражений вы не сможете использовать (?<!A *)(B), поскольку ретроспективный просмотр не исправлен. Вместо этого вы можете использовать ^(?>(?>(?>(?>(?!A *B).)*)A *B)*).*?(B). Обратите внимание, что это может стать очень неэффективным, если аромат также не поддерживает атомарную группировку или притяжательные квантификаторы ... - person JonM; 16.10.2013

Некоторые из других респондентов предложили использовать регулярное выражение, которое не зависит от просмотра назад, но я думаю, что для понимания сути необходим полный рабочий пример. Идея состоит в том, что вы сопоставляете всю последовательность («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', но это не так; он соответствует положению (или границе) между буквой m и пробелом.

Это распространенная ошибка, которую я даже видел повторяющейся в нескольких книгах и учебных пособиях, но конструкция границы слова, \b, никогда не соответствует никаким символам. Это утверждение нулевой ширины, такое как поисковые пути и якоря (^, $, \z и т. Д.), И то, что оно соответствует, - это позиция, которой либо предшествует символ слова и не следует за ним, либо за ней следует символ слова и не предшествует один.

person Alan Moore    schedule 13.02.2009

С javascript вы можете использовать (?=ipsum.*?(\w+))

Это также получит второе вхождение (Nunc)

person JLCDev    schedule 12.07.2017

(?<=\bipsum\s|\bipsum\.\s)(\w+)

/(?<=\bipsum\s|\bipsum\.\s)(\w+)/gm Положительный просмотр назад (?<=\bipsum\s|\bipsum\.\s) Подтвердите, что регулярное выражение ниже соответствует

  1. 1-я альтернатива \bipsum\s \ b утверждает позицию на границе слова: (^\w|\w$|\W\w|\w\W) ipsum буквально соответствует символам ipsum (с учетом регистра) \ s соответствует любому пробельному символу (равному [\r\n\t\f\v ])
  2. Вторая альтернатива \bipsum\.\s \ b утверждает позицию на границе слова: (^\w|\w$|\W\w|\w\W) ipsum буквально соответствует символам ipsum (с учетом регистра). соответствует персонажу. буквально (с учетом регистра) \ s соответствует любому символу пробела (равному [\r\n\t\f\v ]) 1-я группа захвата (\ w +) \ w + соответствует любому символу слова (равному [a-zA-Z0-9_])
  • Квантификатор - соответствует от одного до неограниченного раз, столько раз, сколько возможно, возвращая по мере необходимости (жадный) Глобальные флаги шаблона g modifier: global. Все совпадения (не возвращаются после первого совпадения) m модификатор: многострочный. Заставляет ^ и $ совпадать с началом / концом каждой строки (а не только с началом / концом строки)
person Vijay Anand Pandian    schedule 11.11.2020

ipsum \ b (. *) \ b

РЕДАКТИРОВАТЬ: хотя в зависимости от вашей реализации регулярного выражения это может быть голодным и найти все слова после ipsum

person cjk    schedule 13.02.2009
comment
Это будет соответствовать остальной части предложения. - person cletus; 13.02.2009
comment
ты должен сделать это нелицеприятным - person tliff; 13.02.2009
comment
На самом деле это не зависит от реализации, или, по крайней мере, я никогда не встречал реализации регулярного выражения, которая по умолчанию не является жадной. Нежадный - всегда переключатель (по крайней мере, в Perl, PHP, Java и .Net). - person cletus; 13.02.2009
comment
@cletus: реализация регулярного выражения может по определению включать передачу переключателей на вызов функции регулярного выражения - person cjk; 13.02.2009
comment
Да, но все они по умолчанию являются жадными, и вы передаете переключатели, чтобы выключить это (хотя в PHP есть переключатель, который инвертирует поведение *? И +? В жадность, в то время как * и + становятся не жадными). Тем не менее, это переход от значения по умолчанию. - person cletus; 13.02.2009
comment
действительно, это изменение по умолчанию :) - person cjk; 13.02.2009
comment
Даже если вы сделаете его нежадным - например, ipsum \ b (. *?) \ B - он все равно не будет работать. (. *?) Будет просто соответствовать пробелу между 'ipsum' и следующим словом. - person Alan Moore; 13.02.2009

person    schedule
comment
Кажется, это соответствует только ipsum. - person Matthew Taylor; 13.02.2009
comment
Я бы, наверное, сделал это как минимум \ b + (\ w +) - person cletus; 13.02.2009
comment
ipsum \ b + (\ w +) не является допустимым регулярным выражением. - person Matthew Taylor; 13.02.2009
comment
@ Мэтью Тейлор: Это зависит от вашей платформы. Вы не указали, какую платформу / язык используете. - person Ates Goral; 13.02.2009
comment
Понятно. Я использую регулярное выражение Java в OS X. - person Matthew Taylor; 13.02.2009
comment
\ b + соответствует одной или нескольким границам слова, что не имеет смысла, потому что граница слова имеет нулевую длину. Некоторые варианты игнорируют +, но другие отклоняют его как ошибку. Я думаю, что ipsum \ s + (\ w +) - это то, что вы нащупываете. - person Alan Moore; 13.02.2009