Регулярное выражение для разбора курсивного текста?
Предположим, у меня есть следующий текст:
__This_is__ a __test__
Использование двух подчеркиваний для обозначения курсива. Так что я ожидаю This_is
а также test
быть выделенным курсивом. Логика подсказывает, что любой текст между двумя последовательными двойными подчеркиваниями должен быть выделен курсивом, включая любое другое количество подчеркиваний, которые могут быть там. У меня есть:
__([^_]+)__
Что эквивалентно "не двум последовательным подчеркиваниям" в группе 1? Благодарю.
2 ответа
Вариант будет соответствовать двум подчеркиваниям:
__
Затем сделайте отрицательный взгляд вперед, чтобы увидеть, нет ли двух подчеркиваний впереди текущей позиции:
__(?!__)
если это не так, сопоставьте любой символ:
__(?!__).
и повторите предыдущий один или несколько раз:
__((?!__).)+
и, наконец, сопоставьте еще два подчеркивания:
__((?!__).)+__
что является окончательным решением.
Немного демо:
<?php
$text = '__This_is__ a __test__';
preg_match_all('/__(?:(?!__).)+__/', $text, $matches);
print_r($matches);
?>
производит:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
)
как можно увидеть на Ideone.
РЕДАКТИРОВАТЬ
Обратите внимание, что в моей демонстрации я использовал группу без захвата, иначе результат выглядел бы так:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
[1] => Array
(
[0] => s
[1] => t
)
)
то есть последний символ соответствует ((?!__).)
был бы захвачен в группе 1.
Подробнее о группах см.: http://www.regular-expressions.info/brackets.html
$text = '__This_is__ a __test__';
preg_match_all('/(__([\w]+)__)/', $text, $matches);
print_r($matches);