Выберите два последовательных слова регулярным выражением

Поскольку я новичок в регулярных выражениях; Я хочу сделать регулярное выражение для выбора двух последовательных слов.

Например, когда я даю эту фразу: «Привет, люди #RegularExpression сосет!»

Он должен вернуть эти слова:

-Хорошие люди

-people #RegularExpression

– # RegularExpression сосет!

Я попробовал это /\w\s\w/i но это не сработало 🙁

Related of "Выберите два последовательных слова регулярным выражением"

 $s = "Hello people #RegularExpression sucks!"; preg_match_all('~(?=(\S+\s+\S+))\S+\s+~', $s, $matches); print_r($matches[1]); 

вывод:

 Array ( [0] => Hello people [1] => people #RegularExpression [2] => #RegularExpression sucks! ) 

объяснение:

\S+ соответствует одному или нескольким символам без пробелов. Ваш \w был неправильным по двум причинам: он соответствует только одному символу; и он соответствует только так называемому символу слова (эквивалентному [A-Za-z0-9_] ). Добавление этого параметра в ваш тестовый пример не обязательно, но нет причин не добавлять его, а лишние пробелы имеют способ проникнуть в текст в реальном мире. (Но будьте уверены и добавьте + , а не * ; там должен быть хотя бы один пробельный символ).

(?=...) является положительным взглядом . Вы используете их, чтобы проверить, возможно ли соответствовать вложенному подвыражению в текущей позиции совпадения, не продвигая позицию соответствия. Затем, как правило, вы идете вперед и сопоставляете другое подвыражение, а не в виде.

Вот сложный бит: хотя символы, совпадающие с подвыражением lookahead, не потребляются , любые группы захвата в подвыражении работают как обычно. Представление в моем регулярном выражении (?=(\S+\s+\S+)) соответствует и фиксирует следующую последовательность из двух слов. Затем (при условии, что просмотр выполнен успешно) \S+\s+ соответствует обычным образом, правильно установив позицию соответствия для следующей попытки.

Этот метод должен работать в любом регулярном выражении, который поддерживает захват групп и взглядов. Это включает в себя PHP, а также все другие основные языки (Perl, JavaScript, .NET, Python, Java …). Метод доступа только к содержимому первой группы захвата из каждого матча сильно варьируется от одного языка к другому, но PHP упрощает его с помощью $matches[1] .

Ваше регулярное выражение фактически соответствует двум буквам, разделенным пробелом. Таким образом, с вашим вводом вы получите op и ns . Другая проблема с этим делает глобальный поиск регулярных выражений в строке возвращает неперекрывающиеся экземпляры. Таким образом, правильное регулярное выражение может возвращать Hello people , #RegularExpression sucks! , но он не будет возвращать people #RegularExpression поскольку это перекрывается с Hello people . Третий вопрос: как вы определяете слово? Классическое определение, используемое атомом \w , является буквенно-цифровым или подчеркивающим. Таким образом, #RegularExpression не будет соответствовать, потому что # не является символом слова.

В целом, похоже, что вы действительно хотите сделать, просто разделите свою строку на пробелы, а затем вы можете собрать все пары слов самостоятельно. Вы можете сделать раскол с чем-то вроде preg_split('/\s+/', $str) чтобы вернуть массив всех слов, разделенных пробелами, и затем вы можете перебирать массив, как хотите.

Я уверен, что это возможно сделать с регулярным выражением, но рассол здесь – регулярные выражения, которые потребляют часы, которые они соответствуют, поэтому «вернуться», чтобы получить совпадающие совпадения, является сложной задачей. Regex не подходит для этого; молоток не сосать, потому что он не может (правильно) отрегулировать винты.

Если бы я был вами, я бы просто сделал:

 $str = "Hello people #RegularExpression does not suck!"; $arr = explode(' ', $str); for ($i=0; $i<count($arr) - 1; $i++) { echo implode(' ', array_slice($arr, $i, 2)) . "\n"; } 

Выходы:

 Hello people people #RegularExpression #RegularExpression does does not not suck! 

Как и другие, это кажется невозможным ( EDIT: Ой, это неправильно, см. Ответ Алана ) в стандартном регулярном выражении pcre, и вам лучше выбрать другую стратегию.

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

См. Раздел «УПРАВЛЕНИЕ РЕГУЛИРОВКОЙ» в документе pcre.org/pcre.txt

Эта модель должна работать:

 /[^\s]+\s[^\s]+/i 

Соответствует каждому пробелу, за которым следует одиночный символ пробела и другие символы без пробелов.