这与正则表达式非常相关,以匹配外部括号,但是,我特别想知道如何或是否可以执行此正则表达式的递归模式?我还没有找到使用这个策略的python示例,所以认为这应该是一个有用的问题!
我已经看到 了一些 索赔 是递归的模式可以用来匹配平衡括号,但使用Python的没有例子正则表达式包(注:重不支持递归模式,你需要使用正则表达式).
一种说法是语法在b(?:m|(?R))*e哪里:
b是什么开始构造,m是什么可以发生在构造的中间,并且e是在构造的末尾可以发生的
我想在以下内容中提取外部大括号的匹配项:
"{1, {2, 3}} {4, 5}"
["1, {2, 3}", "4, 5"] # desired
Run Code Online (Sandbox Code Playgroud)
请注意,对于内括号,这很容易做到:
re.findall(r"{([^{}]*)}", "{1, {2, 3}} {4, 5}")
['2, 3', '4, 5']
Run Code Online (Sandbox Code Playgroud)
(在我的例子中,我使用的是finditer(在匹配对象上),请看这里.)
所以我曾希望以下或某些变体可行:
regex.findall(r"{(:[^{}]*|?R)}", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:[^{}]*|?R)})", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:.*|(?R))*})", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:.*)|(?R)*})", …Run Code Online (Sandbox Code Playgroud) PCRE具有称为递归模式的功能,可用于匹配嵌套的子组.例如,考虑"语法"
Q -> \w | '[' A ';' Q* ','? Q* ']' | '<' A '>'
A -> (Q | ',')*
// to match ^A$.
Run Code Online (Sandbox Code Playgroud)
它可以在具有模式的PCRE中完成
^((?:,|(\w|\[(?1);(?2)*,?(?2)*\]|<(?1)>))*)$
Run Code Online (Sandbox Code Playgroud)
(示例测试用例:http://www.ideone.com/L4lHE)
abcdefg abc,def,ghi abc,,,def ,,,,,, [abc;] [a,bc;] sss[abc;d] as[abc;d,e] [abc;d,e][fgh;j,k]
<abc> [<a>b;<c,d>,<e,f>] <a,b,c> <a,bb,c> <,,,> <> <><> <>,<> a<<<<>>><a>> <<<<<>>>><><<<>>>>
<z>[a;b] <z[a;b]> [[;];] [,;,] [;[;]] [<[;]>;<[;][;,<[;,]>]>]
<a bc> <abc<de> [a<b;c>;d,e] [a] <<<<<>>>><><<<>>>>> <<<<<>>>><><<<>>> [abc;def;] [[;],] [;,,] [abc;d,e,f]
[<[;]>;<[;][;,<[;,]>]]> <z[a;b>]
.NET中没有递归模式.相反,它为基于堆栈的操作提供了平衡组,以匹配简单的嵌套模式.
是否可以将上述PCRE模式转换为.NET Regex风格?
(是的,我知道最好不要使用正则表达式.这只是一个理论问题.)
我似乎记得DotNet中的正则表达式有一个特殊的机制,允许嵌套结构的正确匹配,如" ( (a ( ( c ) b ) ) ( d ) e )"中的分组.
什么是python相当于这个功能?这可以使用正则表达式实现一些解决方法吗?(虽然这似乎是当前正则表达式的实现不是为此而设计的那种问题)
我知道.net中有关于正则表达式递归的几个问题.我可以写一些复杂的正则表达式,但这个递归超出了我,我只是无法写它.
这是最接近我想要的问题.
但它匹配整个字符串,我希望集合中的匹配最好是最里面的匹配,或者按照某种顺序.它还匹配一个开头字符和一个结束字符.我打开和关闭是2个字符,[!和!]
我的输入字符串将是这样的.
[!a='test' b='[!a='innertest' b='innervalue'!]'!]
Run Code Online (Sandbox Code Playgroud)
我需要首先找到最不合适的部分,[!a='innertest' b='innervalue'!],然后通过我的一个表达树来评估它.然后评估包含它的父级.
有人能帮忙吗?
在阅读了polygenelubricants关于高级正则表达式技术的系列文章后(特别是这个Java正则表达式如何检测回文?),我决定尝试创建自己的PCRE正则表达式来解析回文,使用递归(在PHP中).
我想出的是:
^(([a-z])(?1)\2|[a-z]?)$
Run Code Online (Sandbox Code Playgroud)
我对这个表达式的理解是它应该匹配零个或一个字符(每个小于2个字符的字符串隐含一个回文,以及在递归中考虑奇数长度的回文),或者两个相同的字符分开通过模式的递归.
不幸的是,它似乎没有那样工作,你可以在www.ideone.com/a9T3F上看到.取而代之的是,只有2的弦ñ - 1(.即空字符串,a,aaa,aaaaaaa,一15)重复字符匹配正则表达式.
奇怪的是,如果我改变我的模式,这样的递归是可选的(即^(([a-z])(?1)?\2|[a-z]?)$,见www.ideone.com/D6lJR,它只匹配反复2字符串ñ倍(即空字符串,a,aa,aaaa,aaaaaaaa,一16) .
为什么我的正则表达式没有像我期望的那样工作?
注意那些渴望建议不使用正则表达式的人:
这个问题的关键是学习如何正确使用递归正则表达式.我知道这不是确定字符串是否是回文的有效方法,如果由于某种原因必须确定生产代码中的回文,我就不会使用递归正则表达式; 我只是想了解有关正则表达式高级方面的更多信息.
如何在 XPath 中使用递归 AND 条件选择?
例如,给定此文档:
<root xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
<file name="foo.mp4">
<chunks>
<file>
<chunks>
<file>
<chunks>
<file>1</file>
<file>2</file>
<file>3</file>
<file>4</file>
</chunks>
</file>
<file>
<chunks>
<file>5</file>
<file>6</file>
<file>7</file>
<file>8</file>
</chunks>
</file>
</chunks>
</file>
<file>
<chunks>
<file>
<chunks>
<file>9</file>
<file>10</file>
<file>11</file>
<file>12</file>
</chunks>
</file>
<file>
<chunks>
<file>13</file>
<file>14</file>
<file>15</file>
<file>16</file>
</chunks>
</file>
</chunks>
</file>
</chunks>
</file>
</root>
Run Code Online (Sandbox Code Playgroud)
我只想选择:
<file>1</file>
<file>2</file>
<file>3</file>
<file>4</file>
Run Code Online (Sandbox Code Playgroud)
所以,实际上是这样的:
//[name="foo.mp4"]/chunks/*[1]/chunks/*[1]/*
Run Code Online (Sandbox Code Playgroud)
但采用通用方法——即可以覆盖更深嵌套对象的方法。像这样的东西:
//[name="foo.mp4"]/(chunks/*[1]/)+/*
Run Code Online (Sandbox Code Playgroud)
(cond)+不是 XPath 语法,而是我想要的类似正则表达式的表示。
当谈到PHP和正则表达式时我很无能,但我正在尝试为我的论坛修复一个破损的插件.
我想替换以下内容:
<blockquote rel="blah">foo</blockquote>
Run Code Online (Sandbox Code Playgroud)
同
<blockquote class="a"><div class="b">blah</div><div class="c"><p>foo</p></div></blockquote>
Run Code Online (Sandbox Code Playgroud)
实际上,这部分很简单,我已经部分修复了插件来执行此操作.正在使用以下正则表达式进行preg_replace_callback()替换:
/(<blockquote rel="([\d\w_ ]{3,30})">)(.*)(<\/blockquote>)/u
Run Code Online (Sandbox Code Playgroud)
回调代码是:
return <<<BLOCKQUOTE
<blockquote class="a"><div class="b">{$Matches[2]}</div><div class="c"><p>{$Matches[3]}</p></div></blockquote>
BLOCKQUOTE;
Run Code Online (Sandbox Code Playgroud)
这适用于我上面的例子(非嵌套的块引用).但是,如果块引用是嵌套的,例如在以下示例中:
<blockquote rel="blah">foo <blockquote rel="bloop">bar ...maybe another nest...</blockquote></blockquote>
Run Code Online (Sandbox Code Playgroud)
它不起作用.所以我的问题是,如何使用regex/PHP的组合替换所有嵌套的 blockquotes?我知道在PHP中可以使用递归模式(?R); 以下正则表达式将从包含它们的字符串中提取所有嵌套的blockquotes:
/(<blockquote rel="([\d\w_ ]{3,30})">)(.*|(?R))(<\/blockquote>)/s
Run Code Online (Sandbox Code Playgroud)
但是从那以后我不太确定在preg_replace_callback()回调中要做什么来用上面的替换来替换每个嵌套的blockquote.
任何帮助,将不胜感激.
我想象一个函数,我想使用正则表达式,它将是递归的实例,如<p><strong></strong></p>删除字符串中的所有空HTML标记.如果可能的话,这必须考虑空白.没有疯狂的实例,其中<character在属性值中使用.
我在正则表达式上非常糟糕,但我想这是可能的.你怎么能这样做?
这是我到目前为止的方法:
Public Shared Function stripEmptyHtmlTags(ByVal html As String) As String
Dim newHtml As String = Regex.Replace(html, "/(<.+?>\s*</.+?>)/Usi", "")
If html <> newHtml Then
newHtml = stripEmptyHtmlTags(newHtml)
End If
Return newHtml
End Function
Run Code Online (Sandbox Code Playgroud)
但是我现在的正则表达式是PHP格式,它似乎没有工作.我不熟悉.NET正则表达式语法.
对于所有那些不使用正则表达式的人:我很好奇这种模式无论如何.当然有一种模式可以匹配所有打开/关闭开始标签与标签之间的任何数量的空白(或没有)?我已经看到正则表达式匹配HTML标签与任意数量的属性,一个空标签(如只是<p></p>)等.
到目前为止,我已经在上面的方法中尝试了以下正则表达式模式无效(因为,我有一个带有空段落标记的文本字符串,甚至没有被删除.)
Regex.Replace(html, "/(<.+?>\s*</.+?>)/Usi", "")
Regex.Replace(html, "(<.+?>\s*</.+?>)", "")
Regex.Replace(html, "%<(\w+)\b[^>]*>\s*</\1\s*>%", "")
Regex.Replace(html, "<\w+\s*>\s*</\1\s*>", "")
我有这个代码:
$string="some text {@block}outside{@block}inside{@}outside{@} other text";
function catchPattern($string,$layer){
preg_match_all(
"/\{@block\}".
"(".
"(".
"[^()]*|(?R)".
")*".
")".
"\{@\}/",$string,$nodes);
if(count($nodes)>1){
for($i=0;$i<count($nodes[1]); $i++){
if(is_string($nodes[1][$i])){
if(strlen($nodes[1][$i])>0){
echo "<pre>Layer ".$layer.": ".$nodes[1][$i]."</pre><br />";
catchPattern($nodes[1][$i],$layer+1);
}
}
}
}
}
catchPattern($string,0);
Run Code Online (Sandbox Code Playgroud)
这给了我这个输出:
Layer 0: outside{@block}inside{@}outside
Layer 1: inside
Run Code Online (Sandbox Code Playgroud)
一切都还可以!但是如果我改变一个字符串和正则表达式:
$string="some text {@block}outside{@block}inside{@end}outside{@end} other text";
function catchPattern($string,$layer){
preg_match_all(
"/\{@block\}".
"(".
"(".
"[^()]*|(?R)".
")*".
")".
"\{@end\}/",$string,$nodes);
if(count($nodes)>1){
for($i=0;$i<count($nodes[1]); $i++){
if(is_string($nodes[1][$i])){
if(strlen($nodes[1][$i])>0){
echo "<pre>Layer ".$layer.": ".$nodes[1][$i]."</pre><br />";
catchPattern($nodes[1][$i],$layer+1);
}
}
}
}
}
catchPattern($string,0);
Run Code Online (Sandbox Code Playgroud)
我没有得到任何输出.为什么?我期待相同的输出.
recursive-regex ×10
regex ×9
.net ×3
pcre ×2
php ×2
python ×2
brackets ×1
c# ×1
html-parsing ×1
palindrome ×1
perl ×1
recursion ×1
xml ×1
xpath ×1