繁体   English   中英

正则表达式选择锚标记而不是值

[英]regular expression to select anchor tag not the value

我需要正则表达式来选择完整的锚标记,除了它的值。

我试过使用下面的正则表达但没有运气

(<a\s\b(href|title)\b.*\">)?|(<[\/]a>) for the below use cases

1.<a href=\"http://www.ags.ny.gov/\">www.ags.ny.gov</a>

2.<a title=\"ba.com/redeem\" href=\"http://ba.com/rertem\" target=\"_blank\" rel=\"nkiops noreferrer\">ba.com/rertem</a>.

3.<a href=\"http://www.dfs.ny.gov/\">www.ags.ay.gov</a>, for free information

我希望输出它应该只选择锚标签以title或href开头,但是它在最后选择锚标记虽然第一个条件不满足参考链接: https//regex101.com/r/VcAS6l/1

我将假设您确实希望在更大的文档中找到锚标记,并且您希望该过程准确且相对有效。

匹配包含(仅)特定类型的开始锚标记结束锚标记的字符串是没有用的。 特别是因为在第一种情况下你没有检查它是否格式正确(请参阅关于'=''"' )或在正则表达式中提取锚点的URL。

让我们分析你的正则表达式:

  (<a\s\b(href|title)\b.*\">)?|(<[\/]a>) 

也就是说匹配的可选<a ...>标签匹配的非可选的<\\a>标记。 它将很乐意匹配可选组的任何实例; 即一无所获。 ? 可能是错位的。

现在看着这个

  <a\s\b(href|title)\b.*\">

说的是:

  1. '<'
  2. 'a'
  3. 空间角色
  4. 一个词边界
  5. "href""title"组成的组
  6. 一个词边界
  7. 零个或多个字符
  8. '"'
  9. '>'

一个小问题是4.是多余的。

更大的问题是您没有明确匹配应该遵循href或title属性名称的'=''"'

最大的问题在于7. '*'中的'.*'是一个贪婪的量词。 它试图尽可能地匹配。 所以在实践中它会一直匹配到文档中的最后一个'"''>' 。这是错误的。

要解决最大的问题,您需要使用不情愿的量词。 一个匹配尽可能少的字符的人。 例如:

    .*?"

将(最初)在它看到的第一个'"'处停止匹配。


教训:

  1. 使用正则表达式来解析结构化文档是一个坏主意。 HTML特别困难,因为:

    • HTML文档的语法有很多法律上的可变性
    • 您将在野外找到的许多HTML文档格式不正确。

      相反,使用适当的解析器。 例如,Jsoup解析器是解析可能在语法上无效的HTML文档的好选择。 它将尝试(内部)纠正错误,而不是无法拒绝文档。

  2. 如果你要“借用”其他人的正则表达式,你依靠他们正确的正则表达式的能力,以及能否理解他们的正则表达式是否(真的)适用于你的问题。 (他们是否正确地做了?假设他们可能在您的用例中有效吗?)

  3. 如果你想尝试写自己的正则表达式解析复杂的文件,你需要了解(Java)的正则表达式语言。 有一些讨厌的陷阱; 例如,热切的量化和灾难性的回溯。

  4. 如果必须调试正则表达式,则需要将其视为任何其他代码调试问题:

    • 确保你理解(正则表达式)的语言
    • 仔细阅读您的代码(正则表达式)。
    • 向你的橡皮鸭解释你的代码(正则表达式)。 (不是开玩笑。)
    • 等等。

如果这听起来太难, 请不要使用正则表达式来解决复杂问题。

此表达式可能是一个查看的选项:

<a\s+(?:href|title)=[^>]*>([^<]*)<\/a>

演示

测试

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class re{

    public static void main(String[] args){

        final String regex = "<a\\s+(?:href|title)=[^>]*>([^<]*)<\\/a>";
        final String string = "<a href=\\\\\\\"http://www.dfs.ny.gov/\\\\\\\">www.dfs.ny.gov</a>, for free information on comparative credit card rates, fees and grace periods.&nbsp;</span>\";\n\n"
             + "<a title= \"some title\" href=\\\\\\\"http://www.dfs.ny.gov/\\\\\\\">www.dfs.ny.gov</a>, for free information on comparative credit card rates, fees and grace periods.&nbsp;</span>\";\n\n"
             + "<a nottitle= \"some title\" href=\\\\\\\"http://www.dfs.ny.gov/\\\\\\\">www.dfs.ny.gov</a>, for free information on comparative credit card rates, fees and grace periods.&nbsp;</span>\";\n\n\n"
             + "<a id=\\\"OLE_LINK2\\\" class=\\\"bookmark\\\" title=\\\"OLE_LINK2\\\" name=\\\"OLE_LINK2\\\"></a>\n\n";
        final String subst = "$1";

        final Pattern pattern = Pattern.compile(regex);
        final Matcher matcher = pattern.matcher(string);

        final String result = matcher.replaceAll(subst);

        System.out.println(result);


    }
}

产量

www.dfs.ny.gov, for free information on comparative credit card rates, fees and grace periods.&nbsp;</span>";

www.dfs.ny.gov, for free information on comparative credit card rates, fees and grace periods.&nbsp;</span>";

<a nottitle= "some title" href=\\\"http://www.dfs.ny.gov/\\\">www.dfs.ny.gov</a>, for free information on comparative credit card rates, fees and grace periods.&nbsp;</span>";


<a id=\"OLE_LINK2\" class=\"bookmark\" title=\"OLE_LINK2\" name=\"OLE_LINK2\"></a>

RegEx电路

jex.im可视化正则表达式:

在此输入图像描述


如果您希望简化/修改/探索表达式,请在regex101.com的右上方面板中进行说明 如果您愿意,您还可以在此链接中查看它与某些示例输入的匹配情况。


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM