这是我的文字:
这是[d]某些[d [um] my]文字。如何[se [le] ct i [nn] b]参加比赛[比赛] [比赛]在比赛中进行比赛
必须突出显示上述文本的正则表达式,如下所示
这是[d]我[d
[um]
我的]文字。如何[se[le]
ct i[nn]
er b]与[b {[out s]
一个tex [[ct]
ele[in]
吨
正如您所看到的,正则表达式必须仅突出显示具有父括号的大括号。不得选择没有父括号的大括号。
例如[is]和s [o] me没有父括号因此不能突出显示。但[d [um]
my],[se [le]
ct i [nn]
er b]种族有父母大括号,因此必须选择括号和内部文本。
我尝试过以下PCRE正则表达式:
\[[^\[]+?]
https://regex101.com/r/xR0wM3/12
但它也突出了没有外支撑的牙箍。这是唯一需要解决的问题,所有其他突出显示的文本都是完美的。在提供的示例中,必须进行更改,以使其不能选择没有父括号的大括号。即,在示例中[is]
正在选择超出要求范围的范围。如果这个问题得到解决,那么我的要求就完成了。
答案 0 :(得分:3)
记住
只有一个父级括号,即只有一个嵌套级别。
您可以在 PHP 中使用以下正则表达式:
(?:\[|(?!^)\G).*?(\[[^\[\]]*\])
请参阅demo
(?:\[|(?!^)\G)
部分将确保我们仅匹配另一对[...]
内的[...]
。
一个更优化的变体没有捕获组并使用\K
(省略匹配的整个初始部分):
(?:\[|(?!^)\G)[^\[\]]*\K\[[^\[\]]*\]
请参阅demo 2
JavaScript的方法包括两个步骤:
var re = /[^\[]+(\[(?:[^\[\]]|\[[^\[\]]*\])*\])/g;
[...]
从这些块中提取所有内部rx = /\[[^\[\]]+\](?=(?:[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*\]))/g;
子字符串。
var re = /[^\[]+(\[(?:[^\[\]]|\[[^\[\]]*\])*\])/g;
var str = 'This [is] some [d[um]my] text. How to [se[le]ct i[nn]er b]race wi[th[out s]ele[ct]ing th]e outer b[race [in] a tex]t';
var m;
while ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
rx = /\[[^\[\]]+\](?=(?:[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*\]))/g;
var n;
while ((n = rx.exec(m[1])) !== null) {
if (n.index === rx.lastIndex) {
rx.lastIndex++;
}
document.getElementById("r").innerHTML += n[0]+"<br/>";
}
}
<div id="r"/>
关于第二个正则表达式的几句话:(?=(?:[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*\]))
前瞻是确保除了[
和]
([^\[\]]*
)之外还有其他字符,或{ {1}}子字符串([...]
)然后关闭\[[^\[\]]*\]
。它可以写成]
,但我使用的解包版本效率更高(虽然看起来非常不整洁。这是JS,对不起。)