Java 正则表达式中的使用条件

Java 正则表达式中的使用条件,java,regex,exception,Java,Regex,Exception,资料来源: 正则表达式: <TD> <A HREF="/home"><IMG SRC="/images/home.gif"></A> <IMG SRC="/images/spacer.gif"> <A HREF="/search"><IMG SRC="/images/search.gif"></A> <IMG SRC="/images/spacer.gif">

资料来源:

正则表达式:

<TD>
    <A HREF="/home"><IMG SRC="/images/home.gif"></A>
    <IMG SRC="/images/spacer.gif">
    <A HREF="/search"><IMG SRC="/images/search.gif"></A>
    <IMG SRC="/images/spacer.gif">
    <A HREF="/help"><IMG SRC="/images/help.gif"></A>
</TD>
结果:

  (<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*</[Aa]>)
这是什么意思

当我在Java中运行它时,它会导致一个异常:Java.util.regex.PatternSyntaxException ?1无法识别

书中的解释是:


此模式需要解释。]+>\s*?是否将开头或标记与可能存在的任何属性相匹配(如果存在结尾)?使表达式成为可选的。]+>然后将标记与其任何属性进行匹配,而不考虑大小写?1\s*以一个条件开始:?1表示如果backreference 1开始标记存在,则仅执行下一步;换句话说,如果第一次匹配成功,则仅执行下一步。如果存在1,则\s*匹配结尾标记后面的任何尾随空格。

是否为非捕获组,如下所述:

还有一个特殊的群体,群体 0,它始终表示整个 表示这一组不包括在内 在groupCount报告的总数中。 从什么开始?是纯洁的,, 未捕获的组 捕获文本,不计入 这组人的总数。您将看到示例 中稍后的非捕获组 Pattern类的section方法


简单的回答是:它没有任何意义。问题在于整个片段:

<A HREF="/home"><IMG SRC="/images/home.gif"></A>
<IMG SRC="/images/spacer.gif">
<A HREF="/search"><IMG SRC="/images/search.gif"></A>
<IMG SRC="/images/spacer.gif">
<A HREF="/help"><IMG SRC="/images/help.gif"></A>
创建反向引用,以便可以重用内部匹配的任何文本。它们还允许您将运算符应用于其中的所有内容,但在您的示例中没有这样做

??这意味着之前的项目应该匹配,如果有,但如果没有也可以。当它在之后出现时,这根本没有意义

?:MoreTextHere 当您不需要重用匹配的文本时,可以使用它来加速正则表达式。但这仍然没有真正的意义,当您的输入是HTML时,为什么要匹配1呢

尝试:


您从未说过要匹配的内容,因此如果这个答案不符合您的要求,请解释您试图使用正则表达式执行的操作。

语法正确。奇怪的样子?。。。。设置条件值。这是if…then语句的正则表达式语法。1是对正则表达式开头的捕获组的反向引用,它匹配一个html,正如Bryan所说,您看到的是一个条件构造,Java不支持它们。紧跟在问号后面的括号表达式实际上可以是任何零宽度断言,如lookahead或lookahead,而不仅仅是对捕获组的引用。我宁愿收回那些断言,以避免混淆。back引用与捕获组匹配的内容相同,但是back断言只是断言捕获组匹配了一些内容

几年前,当我在Perl中工作时,我学习了条件语句,但在Java中我从未错过过它们。例如,在这种情况下,一个简单的替换就可以做到:

(?:<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>
条件版本的一个优点是,您可以使用单个捕获组捕获IMG标记:

(?i)<a\s+[^>]+>\s*<img\s+[^>]+>\s*</a]>|<img\s+[^>]+>
在alternation版本中,每个备选方案都必须有一个捕获组,但这在Java中并不像在Perl中那样重要,因为它具有内置的正则表达式魔力。以下是我如何在Java中提取IMG标记:

(?i)(<a\s+[^>]+>\s*)?(<img\s+[^>]+>)(?(1)\s*</a>)

看看]+>\s*?所以是可选的,如果文本刚刚有,那么?1将返回false,而不是excuteYes。我编辑了我的回复,添加了一个链接,链接到一个关于regex条件句的优秀资源。正如Bryan所说,对于支持条件句的regex风格来说,语法是正确的,但是Java不支持。在10分钟内自学正则表达式对于阅读此问题的任何人,请注意,正则表达式的标准Java包Java.util.regex不支持正则表达式中的条件。关于反向引用和反向断言之间的区别,这一点很好。另外,+1用于提供使用交替的解决方案。
(?i)(<a\s+[^>]+>\s*)?(<img\s+[^>]+>)(?(1)\s*</a>)
Pattern p = Pattern.compile(
  "<a\\s+[^>]+>\\s*(<img\\s+[^>]+>)\\s*</a>|(<img\\s+[^>]+>)"
  Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(s);
while (m.find())
{
  System.out.println(m.start(1) != -1 ? m.group(1) : m.group(2));
}