php
  • regex
  • regex-lookarounds
  • 2013-03-06 2 views 2 likes 
    2

    У меня есть две строки в PHP:PHP регулярное выражение с просмотром назад шаблона

    $string = '<a href="http://localhost/image1.jpeg" /></a>'; 
    

    и

    $string2 = '[caption id="attachment_5" align="alignnone" width="483"]<a href="http://localhost/image1.jpeg" /></a>[/caption]'; 
    

    Я пытаюсь сопоставить строки первого типа. Это строки, которые не окружены '[caption ...]' и '[/ caption]'. До сих пор, я хотел бы использовать что-то вроде этого:

    $pattern = '/(?<!\[caption.*\])(?!\[\/caption\])(<a.*><img.*><\/a>)/'; 
    

    но PHP соответствует из первой строки, а с этого рисунка, даже если это не предваряется «[подпись» и ноль или более символов с последующим " ]». Что дает? Почему это и каков правильный шаблон?

    Спасибо.

    +0

    Почему вы не пытаетесь сопоставить строки, начинающиеся с palindrom

    ответ

    0

    переменная длина Двойник за не поддерживается в PHP, так что эта часть вашего шаблона не является действительной:

    (?<!\[caption.*\]) 
    

    Следует предупреждают об этом.

    Кроме того, .* всегда соответствует наибольшей возможной сумме. Таким образом, ваш шаблон может привести к совпадению, которое перекрывает несколько тегов. Вместо этого используйте [^>] (сопоставьте все, что не является закрывающей скобкой), поскольку закрывающие скобки не должны встречаться внутри тега img.

    Чтобы решить проблему с внешним видом, почему бы не просто проверить только закрывающий тег? Этого должно быть достаточно (предполагая, что теги субтитров используются только так, как показано на рисунке).

    $pattern = '|(<a[^>]*><img[^>]*></a>)(?!\[/caption\])|'; 
    

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

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

    $pattern = '|(<a[^>]*>[^<]*</a>)(?!\[/caption\])|'; 
    

    Обратите внимание, что это не позволяет любых тегов в середине линии. Если вы разрешаете теги (например, используя .*?), регулярное выражение может соответствовать чему-то, начиная с [caption] и заканчивая в другом месте.

    +0

    Ваше решение не будет соответствовать его первой строке ''. – zb226

    +0

    @ zb226, спасибо, что указал. Существует несоответствие между регулярным выражением в вопросе и образцами данных, и я основывал свой ответ на регулярном выражении. – 2013-03-06 14:35:11

    -1

    не касательно предшествующего текста разрешающие не шаблон фиксированной длины, т.е. (*, + ,?), я думаю, что это /<a.*><\/a>(?!\[\/caption\])/ достаточно для вашего требования

    +0

    Это неверно; внешний вид должен находиться в точке в шаблоне, который вы хотите, чтобы он соответствовал (конец строки, а не начало). Отрицательный прогноз всегда будет удовлетворен, потому что он начинает смотреть на ' 2013-03-06 14:31:26

    +0

    Он даже не исключает пример того, что не должно совпадать в вопросе: http://regex101.com/r/kL8yC8 И он определенно не будет работать в реальном мире, где ссылки находятся в более крупном файле. – 2013-03-06 14:36:43

    0

    Я не вижу, как ваше регулярное выражение может соответствовать либо строку, так как вы '' ищет <a.*><img.*><\/a>, и оба якоря не содержат тег <img.... Кроме того, два подвыражения, которые ищут и запрещают биты caption, выглядят странно позиционируемыми для меня. Наконец, вам необходимо убедиться, что ваши биты соответствия меток не действуют жадными, т. Е. Не используют .*, но [^>]*.

    Вы имеете в виду что-то вроде этого?

    $pattern = '/(<a[^>]*>(<img[^>]*>)?<\/a>)(?!\[\/caption\])/' 
    

    Проверьте его на regex101.

    Редактировать: Удалено бесполезное изображение в соответствии с предложением dan1111 и обновленной ссылкой regex101.

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

    • Нет связанных вопросов^_^