使用正则表达式无法匹配字符串

Bet*_*moo 7 java regex

我正在研究一些正则表达式,我想知道为什么这个正则表达式

"(?<=(.*?id(( *)=)\\s[\"\']))g"
Run Code Online (Sandbox Code Playgroud)

与字符串不匹配

<input id = "g" />
Run Code Online (Sandbox Code Playgroud)

在Java?

Mik*_*ike 6

Java.util.regex不支持无限后视,如RegexBuddy所述:

坏消息是,大多数正则表达式都不允许您在lookbehind中使用任何正则表达式,因为它们无法向后应用正则表达式.因此,正则表达式引擎需要能够在检查lookbehind之前找出退回的步骤数.

从文档中添加一些说明:

因此,许多正则表达式,包括Perl和Python使用的那些,只允许固定长度的字符串.您可以使用任何可以预先确定匹配长度的正则表达式.这意味着您可以使用文字文本和字符类.您不能使用重复或可选项.您可以使用交替,但仅当交替中的所有选项具有相同的长度时.

一些正则表达式的风格,如PCRE和Java支持上述,加上不同长度的字符串的交替.交替的每个部分仍必须具有有限的最大长度.这意味着您仍然不能使用星号或加号,但您可以使用问号和带有指定max参数的花括号.这些正则表达式的味道认识到有限重复可以被重写为具有不同但固定长度的字符串的交替.不幸的是,当你在lookbehind中使用交替时,JDK 1.4和1.5有一些错误.这些是在JDK 1.6中修复的.


Ala*_*ore 2

Java 不仅不允许无限制的后向查找,而且如果您尝试,它还会抛出异常。事实上,您没有看到该异常本身就是一个错误

无论如何,你不应该使用lookbehind。如果要匹配某个属性的值,最简单、最不麻烦的方法是匹配整个属性并使用捕获组来提取值。例如:

String source = "<input id = \"g\" />"; 
Pattern p = Pattern.compile("\\bid\\s*=\\s*\"([^\"]*)\"");
Matcher m = p.matcher(source);
if (m.find())
{
  System.out.printf("Found 'id' attribute '%s' at position %d%n",
                    m.group(1), m.start());
}
Run Code Online (Sandbox Code Playgroud)

输出:

Found 'id' attribute 'g' at position 7
Run Code Online (Sandbox Code Playgroud)

帮自己一个忙,暂时忘记回顾。即使它们没有问题,它们也很棘手,而且它们实际上并不像您想象的那么有用。