Joe*_*Joe 1 java regex pattern-matching
我正在为一个Java程序创建一个XMLParser(我知道那里有很好的XMLParser,但我只想这样做).
我有一个名为getAttributeValue(String xmlElement,String attribute)的方法,并使用正则表达式查找具有属性名称加上的字符序列
="any characters that aren't a double quote"
Run Code Online (Sandbox Code Playgroud)
然后我可以解析引号的内容.不幸的是,我在使用正则表达式模式时遇到了麻烦.如果我使用:
Pattern p = Pattern.compile(attribute + "=\"(.)+\"");
Run Code Online (Sandbox Code Playgroud)
然后我得到一个以我的属性名称开头的字符串,但因为有大量的属性和值,并且最后一个的值具有双引号,我得到我想要的字符串以及所有其他属性名称和值,如下所示:
attributeOne="contents" attributeTwo="contents2" attributeThree="contents3"
Run Code Online (Sandbox Code Playgroud)
所以我认为我可以有一个正则表达式,而不是"." 任何字符符号,都有"任何字符,但不是双引号".我试过了:
Pattern p = Pattern.compile(attribute + "=\"(.&&[^\"])+\"");
Pattern p = Pattern.compile(attribute + "=\"(.&&(^\"))+\"");
Pattern p = Pattern.compile(attribute + "=\"([.&&[^\"]]+)\"");
Run Code Online (Sandbox Code Playgroud)
但它们都不起作用.如有任何建议和意见,我将不胜感激.
谢谢.
正则表达式模式:
="any characters that aren't a double quote"
Run Code Online (Sandbox Code Playgroud)
是="[^"]*",作为Java字符串文字"=\"[^\"]*\"".
该[...]构造称为字符类 ; 例如,[aeiou]匹配任何一个小写元音.该[^...]构建体是否定的字符类 ; 例如,[^aeiou]匹配除小写元音(包括辅音,符号,数字等)之外的任何内容.
请注意,这种模式不允许逃跑"的String(见下文为说明这种可能性图案链接).
要理解为什么".+"不按预期"工作",为什么有时候你会看到".+?"不情愿的版本试图"修复"这个问题,请考虑以下示例:
让我们比较这两种模式:A.*Z和A.*?Z.
鉴于以下输入:
eeeAiiZuuuuAoooZeeee
Run Code Online (Sandbox Code Playgroud)
模式产生以下匹配:
A.*Z产生1个匹配:AiiZuuuuAoooZ(见rubular.com)A.*?Z产生2个匹配:AiiZ和AoooZ(参见rubular.com)让我们首先关注的是什么A.*Z.当它匹配的第一个A,在.*,贪婪,首先尝试匹配尽可能多.地.
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Run Code Online (Sandbox Code Playgroud)
由于Z不匹配,引擎会回溯,然后.*必须少一个.:
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
Run Code Online (Sandbox Code Playgroud)
这种情况发生了几次,直到最后我们才发现:
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
Run Code Online (Sandbox Code Playgroud)
现在Z可以匹配,所以整体模式匹配:
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
Run Code Online (Sandbox Code Playgroud)
相比之下,A.*?Z第一次匹配的不情愿重复尽可能少.,然后.根据需要采取更多.这解释了为什么它在输入中找到两个匹配项.
这是两种模式匹配的直观表示:
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
Run Code Online (Sandbox Code Playgroud)
在许多应用中,上述输入中的两个匹配是期望的,因此使用不情愿.*?而不是贪婪.*来防止过匹配.但是,对于这种特殊模式,使用否定字符类有一个更好的选择.
该模式A[^Z]*Z还可以找到与A.*?Z上述输入模式相同的两个匹配项(如ideone.com上所示).[^Z]所谓的否定字符类:它匹配任何东西,但Z.
两种模式之间的主要区别在于性能:更严格,否定的字符类只能匹配给定输入的一种方式.如果你对这个模式使用贪婪或不情愿的修饰符并不重要.事实上,在某些风格中,你可以做得更好,并使用所谓的占有量词,它根本不会回溯.
这个例子应该是说明性的:它显示了在给定相同输入的情况下,贪婪,不情愿和否定的字符类模式如何匹配.
eeAiiZooAuuZZeeeZZfff
Run Code Online (Sandbox Code Playgroud)
这些是上述输入的匹配:
A[^Z]*ZZ产生1个匹配:AuuZZ(上ideone.com所见)A.*?ZZ产生1个匹配:AiiZooAuuZZ(上ideone.com所见)A.*ZZ产生1个匹配:AiiZooAuuZZeeeZZ(上ideone.com所见)以下是它们匹配的直观表示:
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
Run Code Online (Sandbox Code Playgroud)