регулярное выражение для разбора курсивного текста? - PullRequest
2 голосов
/ 02 февраля 2011

Предположим, у меня есть следующий текст:

__This_is__ a __test__

Использование двух подчеркиваний для обозначения курсива. Поэтому я ожидаю, что This_is и test будут выделены курсивом. Логика подсказывает, что любой текст между двумя последовательными двойными подчеркиваниями должен быть выделен курсивом, включая любое другое количество подчеркиваний, которые могут быть там. Я получил:

__([^_]+)__

Что является эквивалентом «не двух последовательных подчеркиваний» в группе 1? Спасибо.

Ответы [ 2 ]

3 голосов
/ 02 февраля 2011

Можно выбрать совпадение двух символов подчеркивания:

__

. Затем сделать отрицательный взгляд вперед и посмотреть, нет ли двух символов подчеркивания перед текущей позицией:

__(?!__)

, еслиэто не так, сопоставьте любой символ:

__(?!__). 

и повторите предыдущий один или несколько раз:

__((?!__).)+

и, наконец, сопоставьте еще два подчеркивания:

__((?!__).)+__

, которое является окончательным решением.

Небольшая демонстрация:

<?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
        )

)

т.е. последний символ*

Подробнее о группах см. http://www.regular -expressions.info / brackets.html

.
1 голос
/ 02 февраля 2011
$text = '__This_is__ a __test__';
preg_match_all('/(__([\w]+)__)/', $text, $matches);
print_r($matches);

http://ideone.com/uHJCC

...