2016-05-16 7 views
0

Я ищу строку 3-431 a4-2 4-13 и хочу найти 3-431, и 4-13. Я использую следующий шаблон:Получите все вхождения между персонажами, чтобы получить тот же результат.

/(.*-.*)*/gU 

и я получаю желаемый результат без проблем: Online demo

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

Если я изменяю предмет по [3-431 a4-2 4-13 ] и регулярному выражению до /\[(.*-.*)*\]/gU, я получаю только последнее происхождение: 4-13, и я не получаю таких же результатов, как в первом примере. Online demo

Почему это и как я могу это исправить?

+0

Почему вы не используете split с ''? –

+0

[Вы можете использовать '/ \ w + - \ w + /' для соответствия] (https://regex101.com/r/wG7uS3/1) – anubhava

+0

Вы не сможете сделать это с помощью одного регулярного выражения. В PCRE количественные группы захвата получают перезапись каждого квантованного прохода, оставляя только последнее значение в группе. Я бы рекомендовал использовать конструкцию '\ G', но это связано с избыточным (дорогим) просмотром каждого совпадения. – sln

ответ

1

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

$str = "3-431 a4-2 4-13"; 
$parts = explode(" ", $str); 
echo $parts [0]; // 3-431 
echo $parts [1]; // a4-2 
echo $parts [2]; // 4-13 

Однако, если вы все еще хотите использовать регулярное выражение, то вы можете использовать:

$re = "/(\\w+-\\w+)/"; 
$str = "3-431 a4-2 4-13"; 

preg_match_all($re, $str, $matches); 

Regex demo

Btw, если ваша строка всегда разделены пробелами, то вы также можете использовать этот рег например:

$re = "/(\\S+)/"; 
$str = "3-431 a4-2 4-13"; 

preg_match_all($re, $str, $matches); 

Regex demo

С другой стороны, если строка начинается и заканчивается [ и ], как [3-431 a4-2 4-13 ]. Идея заключается в том, чтобы использовать технику сброшенных, вы могли бы использовать это регулярное выражение:

[[\]](*SKIP)(*FAIL)|(\S+) 

Working demo

А также, получить тот же результат, используя preg_split для выше строк:

$exploded = preg_split('[[\]\s]+', '[3-431 a4-2 4-13]', NULL, PREG_SPLIT_NO_EMPTY) 
0

Прежде всего, вы должны использовать .+, а не .* с + me по крайней мере один раз. Тогда ваше регулярное выражение:

/\[(\w+-\w+)*\s*\]/sgU 
+0

Вы должны отступать код (и регулярные выражения) 4 пробела, иначе вещи будут перепутаны. – Laurel

0

Если вы все еще хотел сделать регулярное выражение это будет работать:

(^|\])[^[]*\[([^[]*-[^[]*)*(*SKIP)(*FAIL)|(.*-.*)+ 

В принципе, если возникновение происходит вне [ и ] он потерпит неудачу.


Причина, по которой вашему были только получать один матч в том, что глобальный модификатор будет соответствовать только другому появлению после первого матча заканчивается, что в вашем случае было после закрывающей скобки.

 Смежные вопросы

  • Нет связанных вопросов^_^