Как создать шаблон регулярного выражения для простого текста HTML?

Я пытаюсь изучить шаблоны Regex для класса. Я делаю простой HTML Lexer/Parser. Я знаю, что это не лучший и не самый эффективный способ создания лексера/парсера, но он предназначен только для понимания шаблонов регулярных выражений.

Итак, мой вопрос: как мне создать шаблон, который проверяет, не содержит ли строка каких-либо тегов HTML (т.е. <TAG>) и не содержит каких-либо объектов HTML (т.е. &ENT;)?

Это то, что я мог придумать до сих пор, но это все еще не работает:

.+?(^(?:&[A-Za-z0-9#]+;)^(?:<.*?>))

РЕДАКТИРОВАТЬ: Единственная проблема заключается в том, что я не могу отрицать окончательный результат, который мне нужен, чтобы найти полный шаблон, который выполнил бы эту задачу, если это возможно, хотя это может быть некрасиво. Я никогда не упоминал, но в значительной степени предполагается, что он соответствует любому простому тексту на странице HTML.


person Free Lancer    schedule 10.12.2010    source источник


Ответы (2)


Если вы хотите сопоставить строки, которые НЕ соответствуют шаблону, самое простое, что нужно сделать, это сопоставить шаблон, а затем отрицать результат проверки.

<[^>]+>|&[^;]+;

Любая строка, соответствующая этому шаблону, будет иметь ПО КРАЙНЕЙ МЕРЕ ОДИН тег (как вы его определили) или объект (как вы его определили). Таким образом, строки, которые вам нужны, - это строки, которые НЕ соответствуют этому шаблону (у них НЕТ тегов или сущностей).

person Platinum Azure    schedule 10.12.2010
comment
Я бы изменил оба * на + и удалил группу захвата. - person aioobe; 10.12.2010
comment
Возможно ли это? ^(?:‹[^›]+›|&[^;]+;) - person Free Lancer; 11.12.2010
comment
то есть: группировка шаблона, а затем отрицание всего этого в шаблоне. - person Free Lancer; 11.12.2010
comment
Нет, потому что вы не можете отрицать шаблон, только класс символов. Символ ^ вне класса символов работает иначе: он привязывает шаблон к началу строки. (Это причудливый способ сказать, что строка должна начинаться с шаблона, а не просто содержать его) - person Platinum Azure; 11.12.2010

Вы можете использовать выражение <.+?>|&.+?; для поиска соответствия, а затем отрицать результат.

  • <.+?> говорит сначала <, затем что-то (один или несколько раз), затем >
  • &.+?; говорит сначала &, затем что-то (один или несколько раз), затем ;

Вот полный пример с демонстрацией ideone.com здесь.

import java.util.regex.*;

public class Test {
    public static void main(String[] args) {
        String[] tests = { "hello", "hello <b>world</b>!", "Hello&nbsp;world" };
        Pattern p = Pattern.compile("<.+?>|&.+?;");
        for (String test : tests) {
            Matcher m = p.matcher(test);
            if (m.find())
                System.out.printf("\"%s\" has HTML: %s%n", test, m.group());
            else
                System.out.printf("\"%s\" does have no HTML%n", test);
        }
    }
}

Вывод:

"hello" does have no HTML
"hello <b>world</b>!" has HTML: <b>
"Hello&nbsp;world" has HTML: &nbsp;
person aioobe    schedule 10.12.2010