Я работаю несколько часов над регулярным выражением. Например, исходное предложение:
location in [chambre, cuisine, salle-de-bain, jardin]
Всего за один шаг я хочу убедиться, что фигура представляет собой слово в [слово, слово, слово...], и я хотел бы поймать каждое слово. (Я хочу сделать это только в один шаг для производительности, потому что этот код уже работает с тремя шагами, но это слишком долго)
Мое текущее регулярное выражение:
/([a-zA-Z]+)\s+in\s+\[\s*([a-zA-Z-]+)\s*(?:,\s*([a-zA-Z-]+)\s*)*\s*\]/
Я ловлю локацию, chambre и jardin. Я не ловлю кухню и саль-де-бен
$condition = 'location in [chambre, cuisine, salle-de-bain, jardin]'
$analyse = preg_match('/([a-zA-Z]+)\s+in\s+\[\s*([a-zA-Z-]+)\s*(?:,\s*([a-zA-Z-]+)\s*)*\s*\]/',$condition, $matches);
var_dump($matches);
array:4 [▼
0 => "location in [chambre, cuisine, salle-de-bain, jardin]"
1 => "location"
2 => "chambre"
3 => "jardin"
]
Я не нахожу, что не так в моем регулярном выражении, чтобы поймать 2 пропущенных слова. Я получаю только первый и последний в массиве...






В PHP повторяющиеся группы захвата всегда будут сохранять только последнюю захваченную подстроку.
Вы можете использовать preg_match_all с регулярным выражением, например
[a-zA-Z]+(?=\s+in\s+\[\s*[a-zA-Z-]+(?:\s*,\s*[a-zA-Z-]+)*\s*])|(?:\G(?!^)\s*,\s*|(?<=[a-zA-Z])\s+in\s+\[\s*)\K[a-zA-Z-]+(?=(?:\s*,\s*[a-zA-Z-]+)*\s*])
См. демонстрация регулярных выражений. Подробности:
[a-zA-Z]+(?=\s+in\s+\[\s*[a-zA-Z-]+(?:\s*,\s*[a-zA-Z-]+)*\s*]) - одна или несколько букв ASCII, за которыми сразу следует in, заключенная в один или несколько пробельных символов, затем [, ноль или более пробелов, одна или несколько букв ASCII или дефис, затем ноль или более повторений запятой, заключенная в ноль или более пробелы, а затем одна или несколько букв или дефисов ASCII, затем ноль или более пробелов и символ ]| - или(?:\G(?!^)\s*,\s*|(?<=[a-zA-Z])\s+in\s+\[\s*)\K[a-zA-Z-]+(?=(?:\s*,\s*[a-zA-Z-]+)*\s*]):
(?:\G(?!^)\s*,\s*|(?<=[a-zA-Z])\s+in\s+\[\s*) - конец предыдущего совпадения и запятая, заключенная с нулем или более пробелами, или место, которому непосредственно предшествует буква ASCII, затем один или несколько пробелов, in, один или несколько пробелов, [ и ноль или более пробелов\K - пропустить совпадающий текст[a-zA-Z-]+ - одна или несколько букв ASCII или дефисов(?=(?:\s*,\s*[a-zA-Z-]+)*\s*]) - положительный просмотр вперед, который требует ноль или более повторений запятой, заключенной в ноль или более пробелов, а затем одну или несколько букв или дефисов ASCII, затем ноль или более пробелов и символ ].Большое спасибо за ваш полный ответ. Я ценю его!
В PHP повторяющиеся группы захвата всегда будут сохранять только последнюю захваченную подстроку.