php
  • regex
  • preg-replace
  • 2013-05-19 2 views 0 likes 
    0

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

    Что я хочу:

    [segment type="segment_name"]more text here[/segment] 
    

    быть изменен на:

    [segmentclass='segment_name segment']more text here[/segment] 
    

    и:

    [segment]more text here[/segment] 
    

    быть изменен на:

    [segmentclass=' segment']more text here[/segment] 
    

    Вот что у меня есть:

    $pattern = '/(\[segment.*?)(type=\"(.+?)\")?(.*?\[\/segment\])/is'; 
    $replacement = '$1class=\'$3 segment\'$4'; 
    $content = preg_replace($pattern, $replacement, $content); 
    

    Кто-нибудь есть какие-нибудь идеи? ? after (type = \ "(. +?) \") состоит в том, чтобы сделать этот блок необязательным. Кажется, что замена просто пропускает его, потому что это необязательно. Я думаю, что у меня есть проблема с жадностью где-то, но я не смог разобраться.

    Ответьте, если у вас есть идеи по-другому, я тоже мог бы это сделать.

    +0

    У вас нет закрывающего ']' в вашем шаблоне в любом месте. –

    +0

    Это должно быть в порядке с совпадением со вторым. *? и затем включается в 4 доллара США. – eli

    ответ

    1

    У вас нет закрывающего кронштейна ] для блока первого сегмента. Поскольку он не находит соответствия для этого закрывающего блока, .*? соответствует всем [/segment], игнорируя необязательную группу, которую вы там положили.

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

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

    Вход, который вы указали в своем вопросе, а также ваше конкретное соответствие segment заставляет меня поверить, что ваше регулярное выражение слишком сложно, а замена очень грязная. Этому обновленному регулярному выражению также не нужен флаг DOTALL.

    $pattern = '/\[segment(?: type="([^"]+)")?\]/i'; 
    $replacement = '[segmentclass=\'$1 segment\']'; 
    
    +0

    Ну, я не хочу сопоставлять], потому что 3 доллара, которые я хочу, перед]. Это поставило меня на путь попыток получить. *, Чтобы быть лучше. По-видимому. не соответствует пространству. Я изменил его на [.] *, И теперь он работает. Я постараюсь работать над лучшим классом персонажей. Благодарю. – eli

    +1

    В вашем примере текста ничего действительно не указано, что вам понадобится. *? после открытия сегмента. Я обновил ответ, чтобы отразить мои мысли. – melwil

    +0

    Спасибо за обновление. Помогает мне много. :-) – eli

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