Я провел небольшое исследование, но в моем случае ничего не помогло.
У меня есть это регулярное выражение, в котором я могу получить поток № 0: 4, но я хотел бы повторить правило, а также поймать поток № 0: 5. Как мне повторить правило и проигнорировать в середине -> # 0: 0 (copy) -> # 0: 1 (copy)
регулярное выражение
/(?<=Stream mapping:)(\s+)([a-zA-Z])+(\s+)#([0-9]:[0-9])/s
текст
Metadata:
variant_bitrate : 800000
Stream mapping:
Stream #0:4 -> #0:0 (copy)
Stream #0:5 -> #0:1 (copy)
Press [q] to stop, [?] for help
Мой текущий результат
array(1) {
[0]=> array(5)
{
[0]=> string(15) " Stream #0:4"
[1]=> string(4) " "
[2]=> string(1) "m"
[3]=> string(1) " "
[4]=> string(3) "0:4" }
}
Другая проблема заключается в том, что мое регулярное выражение обрабатывает «m» как отдельную комбинацию и включает в себя пустые места. Как я могу это исправить?
Я хотел получить конечный результат вроде
[0]Stream #0:4
[1]Stream #0:5
Проверить ideone.com/YwonZU
Хотя не могу обозначить правильный ответ на свою проблему. Вот что мне было нужно. спасибо @ WiktorStribiżew






Почему не просто
/^ Stream #([\d:]+) -> #([\d:]+) \((.*)\)/gm
который будет соответствовать два раза,
['0:4', '0:0', 'copy'] и['0:5', '0:1', 'copy']Ваш взгляд на (?<=Stream mapping:) - вот что сломало ваш подход. Я не думаю, что это действительно нужно для этого ввода.
Обратите внимание, что с флагом m^ соответствует каждой строке, что здесь полезно.
В тексте есть несколько потоков. Я сократил рассматриваемый код. Мне нужно получить два потока, которые они видят после «Сопоставления потоков:», как показано в коде.
Разделите текст на «Отображение потока» и выполните описанное выше в цикле. Я не вижу причин, по которым использование более сложного регулярного выражения могло бы улучшить ситуацию. Также на будущее укажите свои требования в вопросе. Если у вас несколько потоков, задайте свой вопрос и ваш пример скажите об этом.
Вы можете использовать настраиваемую границу слова на основе оператора \G:
$re = '/(?:\G(?!^)\s*|Stream mapping:\s*)\K([a-zA-Z]+\s+#[0-9]+:[0-9]+).*/';
$str = 'Metadata:
variant_bitrate : 800000
Stream mapping:
Stream #0:4 -> #0:0 (copy)
Stream #0:5 -> #0:1 (copy)
Press [q] to stop, [?] for help';
if (preg_match_all($re, $str, $m)) {
print_r($m[1]);
}
См. Демо PHP.
Детали рисунка:
(?:\G(?!^)\s*|Stream mapping:\s*) - либо конец предыдущего совпадения и 0+ пробелов, либо подстрока Stream mapping:, за которой следует 0+ пробелов\K - оператор сброса совпадения, отбрасывающий текущий совпадающий текст([a-zA-Z]+\s+#[0-9]+:[0-9]+) - Группа 1: 1+ букв, 1+ пробелов, #, 1+ цифр, :, 1+ цифр.* - любые символы 0+ до конца строки (необходимо использовать, так как нам нужны непрерывные совпадения)
Я не совсем уверен, вам нужен regex101.com/r/LP5f9N/2 или regex101.com/r/LP5f9N/3?