【问题标题】:How to make a Regex Pattern for HTML Simple Text?如何为 HTML 简单文本制作正则表达式模式?
【发布时间】:2011-05-23 17:08:14
【问题描述】:

我正在尝试为课程学习正则表达式模式。我正在制作一个简单的 HTML Lexer/Parser。我知道这不是制作 Lexer/Parser 的最佳或最有效的方法,但它只是为了理解 Regex 模式。

所以我的问题是,如何创建一个模式来检查字符串是否不包含任何 HTML 标签(即<TAG>)并且不包含任何 HTML 实体(即&ENT;)?

这是我目前所能想到的,但它仍然不起作用:

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

编辑:唯一的问题是我不能否定最终结果,我需要找到一个完整的模式来完成这项任务,如果可能的话,虽然它可能不漂亮。我从来没有提到过,但它几乎应该匹配 HTML 页面中的任何简单文本。

【问题讨论】:

  • 你为什么不能否定这个模式?我不明白你的推理......
  • 您可以复制您的 HTML 字符串,然后使用下面的正则表达式模式来删除 HTML 标记和实体(用任何内容替换模式)。这给你留下了纯文本(尽管实体已经消失而不是翻译成它们的实际字符)。

标签: java regex posix regex-negation


【解决方案1】:

您可以使用表达式&lt;.+?&gt;|&amp;.+?; 来搜索匹配项,然后否定结果。

  • &lt;.+?&gt; 首先是 &lt; 然后是任何东西(一次或多次)然后是 &gt;
  • &amp;.+?; 首先说 &amp; 然后是任何东西(一次或多次)然后是 ;

这是一个带有ideone.com demo here 的完整示例。

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;

【讨论】:

    【解决方案2】:

    如果您要匹配不遵循模式的字符串,最简单的做法是匹配模式,然后否定测试结果。

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

    任何与此模式匹配的字符串都将具有至少一个标记(如您所定义的那样)或实体(如您所定义的那样)。因此,您想要的字符串是与此模式不匹配的字符串(它们将没有标签或实体)。

    【讨论】:

    • 我会将* 都更改为+ 并删除捕获组。
    • 这可能吗? ^(?:]+>|&[^;]+;)
    • ie:对模式进行分组,然后在模式中否定整个事物。
    • 不,因为你不能否定一个模式,只能否定一个字符类。 ^ 字符,在字符类之外,工作方式不同:它将模式锚定到字符串的开头。 (这是一种奇特的说法,字符串需要以模式开头,而不仅仅是包含它)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 2018-03-21
    • 2011-10-30
    相关资源
    最近更新 更多