Как все говорят, вы не должны полагаться на регулярные выражения для анализа HTML.Они просто не могут этого сделать.Но в моем случае я хотел захватить любые угловые скобки, которые не выглядели так, как будто они были в HTML-теге, и избежать их.Так как все проходило через дезинфицирующее средство, впоследствии безопасность не была проблемой, и результаты должны были быть достаточно хорошими, чтобы охватить большинство ситуаций, а не все.
Вам нужна библиотека Regexp, которая поддерживает предположения нулевой ширины.,В моем случае это был Oniguruma в Ruby 1.8.
Чтобы соответствовать символам меньше, чем (<), я сделал: </p>
/<(?!(/?[A-Za-z_:0-9]+\s?/?>))/
Сравнивать символы больше (>) сложнее.Большинство библиотек не поддерживают утверждения обратной ширины нулевой ширины переменной длины.Итак, вы обманываете: переверните строку, выполните предварительное утверждение и затем верните его обратно, используя следующий шаблон:
>(?!(/?\s?[A-Za-z_:0-9]+/?<))
Итак, мой код выглядит примерно так:
match_less_than = Oniguruma::ORegexp.new('<(?!(/?[A-Za-z_:0-9]+\s?/?>))')
match_less_than.gsub!(string, '<')
match_greater_than = Oniguruma::ORegexp.new('>(?!(/?\s?[A-Za-z_:0-9]+/?<))')
string = match_greater_than.gsub(string.reverse, '>'.reverse).reverse
Противно, да?