我想从xml文件中检索数据。我使用像这样的正则表达式:
/
<OVERLAYLINKPROJECT(?:.|\s)+
<OUTPUT
/xU
这是我的xml文件的摘录:
<OVERLAYLINKPROJECT id='0773C138' parent_id='007285A0' ovl_id='0x4b' run_address='0x9022a' run_size='0x450' live_address='0x40c111' live_size='0x678' >
<FILE_NAME><![CDATA[xxx.ovl]]></FILE_NAME>
<OUTPUT_SECTIONS>
<OUTPUT_SECTION id='0773C138' name='xxxx' type='SHT_PROGBITS' start_address='0x9022a' word_size='0x450' word_size_unmapped='0x0' in_overlay='' >
<INPUT_SECTIONS>
<INPUT_SECTION id='0580D5B0' name='yyyy' start_address='0x9022b' size='0x44f' element_at='0x0' >
正则表达式在没有ungreedy修饰符U
的情况下不起作用。为什么呢?
答案 0 :(得分:2)
令人惊讶的是,问题是catastrophic backtracking。
您使用了(?:.|\s)
,大概是因为.
不匹配换行符,而您的输入包含它们。但是,\s
也匹配其他空格,也可以由.
匹配。
如果您不使用ungreedy修饰符,(?:.|\s)+
首先匹配<OVERLAYLINKPROJECT
后的整个字符串,然后回溯以查看<OUTPUT
首先匹配的位置。在每个空间,它需要尝试将其与.
匹配或与\s
匹配之前的所有备选方案,然后才能确保它们都不会导致有效匹配。
字符串的那一部分有14个空格。每一个都必须与所有其他组合进行检查,结果为14! (= 87178291200)所有必须检查的排列。这需要一段时间(或正则表达式引擎超时)。
当您使用ungreedy修饰符时,正则表达式引擎会逐步匹配一个字符,&#34;标记&#34;每个空格用于以后评估,以防匹配失败 - 但只要遇到<OUTPUT
就会成功。这就是为什么它匹配得更快。如果输入字符串不包含<OUTPUT
,它仍然会灾难性地失败 - 因为在这种情况下,正则表达式引擎需要重新访问所有空格并尝试不同的排列,这是徒劳的希望找到匹配的方式。
使用/s
修饰符来允许点匹配换行符:
/
<OVERLAYLINKPROJECT.+
<OUTPUT
/xs
答案 1 :(得分:0)
<OVERLAYLINKPROJECT(?:.|\s)+?<OUTPUT
试试这个。看看演示。
http://regex101.com/r/bW3aR1/1
正如蒂姆所解释的那样,你的正则表达式的问题是灾难性的回溯。