如何匹配开始和结束花括号内的文本,标签和指定的属性
How to match text inside starting and closing curly brace, the tags and the specified attributes
我正在为我的 CMS 系统实现一个插件代码。类似于短代码,但适用于许多场景。我想要一个管理员这样写他的代码的情况:
示例 1:
{COMMAND_NAME}Strings of texts that conatains htmltags,symbols,just anything{/COMMAND_NAME}
示例 2
{COMMAND_NAME}
示例 3
{COMMAND_NAME{attriute1=value attribute2=value}}
示例 4
{COMMAND_NAME{attriute1=value attribute2=value}}Strings of anything including texts, htmltags and anything at all {/COMMAND_NAME}
正则表达式可以匹配上面的字符串。从单个正则表达式模式中获取 COMMAND_NAME
、获取其间的文本并获取结尾 {/COMMAND_NAME}
。
在正则表达式中,我想捕获 COMMAND_NAME
,属性(如果提供的话),如果 {COMMAND_NAME}
有结束符 {/COMMAND_NAME}
和结束符 {/COMMAND_NAME}
如果提供。
看看我到目前为止做了什么并得出一些不完整的结果。
$regex = #\{(RAW|ACCESS|DWNLINK|MODL)[\{]{0,1}([\w\W\s]*?)\}{0}\}([\w\s]+)([\{/RAW|ACCESS|DWNLINK|MODL]*)\}#i
$strings = '<div class="blog-list-item blog"><header class="entry-title">
<h1>Welcome to our website</h1>
</header><article id="entry-72" class="entry post-72 page et-bg-layout-dark et-white-bg"><div class="jumbotron row">
<div class="col-md-8">
<ul>
<li>You have a pending job on your neck?…</li>
<li>Do your company need a website makeover ?…</li>
<li>Or a competitive web application ? ?…</li>
<li>Do you need a customized plugin, or a tweak ?…</li>
<li>Maybe you want a personal website ?…</li>
<li>Or a graphic for your new project ?…</li>
</ul>
<div class="bg-primary well">
<h4 class="text-center text-white shadow">Track your project as we work it to perfection...</h4>
</div>
</div>
<div class="pull-right col-md-4">
<h4 class="bg-primary text-white well">Other services we offer</h4>
{ACCESS{type=500}}
<ul>
<li>SEO work for an existing website or new</li>
<li>Bulk SMS</li>
<li>E-currency exchange</li>
<li>Facebook AD</li>
<li>Google AD</li>
</ul>
{/ACCESS}</div>
{RAW{say=email,access=500}} {RAW} <a class="btn button large tall green" href="client-area">Place new Job now as we deliver at the quickest <em>reasonable time</em></a>{/RAW}</div></article></div>';
And doing a php var_dump, gives the following result:
array(5) {
[0]=>
array(1) {
[0]=>
string(224) "{ACCESS{type=500}}
<ul>
<li>SEO work for an existing website or new</li>
<li>Bulk SMS</li>
<li>E-currency exchange</li>
<li>Facebook AD</li>
<li>Google AD</li>
</ul>
{/ACCESS}</div>
{RAW{say=email,access=500}} {RAW}"
}
[1]=>
array(1) {
[0]=>
string(6) "ACCESS"
}
[2]=>
array(1) {
[0]=>
string(209) "type=500}}
<ul>
<li>SEO work for an existing website or new</li>
<li>Bulk SMS</li>
<li>E-currency exchange</li>
<li>Facebook AD</li>
<li>Google AD</li>
</ul>
{/ACCESS}</div>
{RAW{say=email,access=500}"
}
[3]=>
array(1) {
[0]=>
string(1) " "
}
[4]=>
array(1) {
[0]=>
string(4) "{RAW"
}
}
这实际上不是我需要检索的。
再一次,我想捕获 COMMAND_NAME
,仅当提供时才捕获属性,如果 {COMMAND_NAME}
具有结束 {/COMMAND_NAME}
和结束 {/COMMAND_NAME}
(如果提供)之间的文本。这意味着该命令可以是内联的 {COMMAND_NAME}
,也可以不是 {COMMAND_NAME}
一些字符串 {/COMMAND_NAME}
,具有属性 {COMMAND_NAME{attr1=value attr2=value2}}
或没有。
此正则表达式将按您指定的方式工作:
$regex = '~
#opening tag
\{(RAW|ACCESS|DWNLINK|MODL|\w+)
#optional attributes
(?>
\{ ([^}]*) }
)?
}
#optional text and closing tag
(?:
( #text:= any char except "{", or a "{" not followed by /commandname
[^{]*+
(?>\{(?!/?[{}])[^{]*)*+
)
#closing tag
( \{/} )
)?
~ix';
与你拥有的相比:
首先,我使用了 /x
修饰符(最后),它忽略了空格和 #comments
.
在起始标签中,我使用了你的选项,但你也可以使用\w+
来匹配任何命令名称:
\{(RAW|ACCESS|DWNLINK|MODL|\w+)
对于可选属性,您有 [\{]{0,1}([\w\W\s]*?)\}{0}
,这是使每个部分都可选的有效尝试。相反,我使用的是 (?> group )?
(参见 non-capturing groups and atomic groups) to make the whole subpattern optional (with the ?
quantifier)。
(?>
\{ ([^}]*) }
)?
相同的逻辑应用于文本和结束标记,使其成为可选的。
您使用 [\w\s]+
来匹配文本,它匹配单词字符和空格,但无法匹配标点符号和其他字符。我本可以使用 .*?
,它也能正常工作。但是,我使用了以下结构,它匹配相同,但性能更好:
( #text:= any char except "{", or a "{" not followed by /commandname
[^{]*+
(?>\{(?!/?[{}])[^{]*)*?
)
最后,我使用 </code> 匹配结束标签,这是对组 1 中匹配的文本(开始标签名称)的反向引用:</p>
<pre><code>\{/}
假设:
- 属性在引号中没有右括号,例如
"te}xt"
可能会导致它中断。
我正在为我的 CMS 系统实现一个插件代码。类似于短代码,但适用于许多场景。我想要一个管理员这样写他的代码的情况:
示例 1:
{COMMAND_NAME}Strings of texts that conatains htmltags,symbols,just anything{/COMMAND_NAME}
示例 2
{COMMAND_NAME}
示例 3
{COMMAND_NAME{attriute1=value attribute2=value}}
示例 4
{COMMAND_NAME{attriute1=value attribute2=value}}Strings of anything including texts, htmltags and anything at all {/COMMAND_NAME}
正则表达式可以匹配上面的字符串。从单个正则表达式模式中获取 COMMAND_NAME
、获取其间的文本并获取结尾 {/COMMAND_NAME}
。
在正则表达式中,我想捕获 COMMAND_NAME
,属性(如果提供的话),如果 {COMMAND_NAME}
有结束符 {/COMMAND_NAME}
和结束符 {/COMMAND_NAME}
如果提供。
看看我到目前为止做了什么并得出一些不完整的结果。
$regex = #\{(RAW|ACCESS|DWNLINK|MODL)[\{]{0,1}([\w\W\s]*?)\}{0}\}([\w\s]+)([\{/RAW|ACCESS|DWNLINK|MODL]*)\}#i
$strings = '<div class="blog-list-item blog"><header class="entry-title">
<h1>Welcome to our website</h1>
</header><article id="entry-72" class="entry post-72 page et-bg-layout-dark et-white-bg"><div class="jumbotron row">
<div class="col-md-8">
<ul>
<li>You have a pending job on your neck?…</li>
<li>Do your company need a website makeover ?…</li>
<li>Or a competitive web application ? ?…</li>
<li>Do you need a customized plugin, or a tweak ?…</li>
<li>Maybe you want a personal website ?…</li>
<li>Or a graphic for your new project ?…</li>
</ul>
<div class="bg-primary well">
<h4 class="text-center text-white shadow">Track your project as we work it to perfection...</h4>
</div>
</div>
<div class="pull-right col-md-4">
<h4 class="bg-primary text-white well">Other services we offer</h4>
{ACCESS{type=500}}
<ul>
<li>SEO work for an existing website or new</li>
<li>Bulk SMS</li>
<li>E-currency exchange</li>
<li>Facebook AD</li>
<li>Google AD</li>
</ul>
{/ACCESS}</div>
{RAW{say=email,access=500}} {RAW} <a class="btn button large tall green" href="client-area">Place new Job now as we deliver at the quickest <em>reasonable time</em></a>{/RAW}</div></article></div>';
And doing a php var_dump, gives the following result:
array(5) {
[0]=>
array(1) {
[0]=>
string(224) "{ACCESS{type=500}}
<ul>
<li>SEO work for an existing website or new</li>
<li>Bulk SMS</li>
<li>E-currency exchange</li>
<li>Facebook AD</li>
<li>Google AD</li>
</ul>
{/ACCESS}</div>
{RAW{say=email,access=500}} {RAW}"
}
[1]=>
array(1) {
[0]=>
string(6) "ACCESS"
}
[2]=>
array(1) {
[0]=>
string(209) "type=500}}
<ul>
<li>SEO work for an existing website or new</li>
<li>Bulk SMS</li>
<li>E-currency exchange</li>
<li>Facebook AD</li>
<li>Google AD</li>
</ul>
{/ACCESS}</div>
{RAW{say=email,access=500}"
}
[3]=>
array(1) {
[0]=>
string(1) " "
}
[4]=>
array(1) {
[0]=>
string(4) "{RAW"
}
}
这实际上不是我需要检索的。
再一次,我想捕获 COMMAND_NAME
,仅当提供时才捕获属性,如果 {COMMAND_NAME}
具有结束 {/COMMAND_NAME}
和结束 {/COMMAND_NAME}
(如果提供)之间的文本。这意味着该命令可以是内联的 {COMMAND_NAME}
,也可以不是 {COMMAND_NAME}
一些字符串 {/COMMAND_NAME}
,具有属性 {COMMAND_NAME{attr1=value attr2=value2}}
或没有。
此正则表达式将按您指定的方式工作:
$regex = '~
#opening tag
\{(RAW|ACCESS|DWNLINK|MODL|\w+)
#optional attributes
(?>
\{ ([^}]*) }
)?
}
#optional text and closing tag
(?:
( #text:= any char except "{", or a "{" not followed by /commandname
[^{]*+
(?>\{(?!/?[{}])[^{]*)*+
)
#closing tag
( \{/} )
)?
~ix';
与你拥有的相比:
首先,我使用了 /x
修饰符(最后),它忽略了空格和 #comments
.
在起始标签中,我使用了你的选项,但你也可以使用\w+
来匹配任何命令名称:
\{(RAW|ACCESS|DWNLINK|MODL|\w+)
对于可选属性,您有 [\{]{0,1}([\w\W\s]*?)\}{0}
,这是使每个部分都可选的有效尝试。相反,我使用的是 (?> group )?
(参见 non-capturing groups and atomic groups) to make the whole subpattern optional (with the ?
quantifier)。
(?>
\{ ([^}]*) }
)?
相同的逻辑应用于文本和结束标记,使其成为可选的。
您使用 [\w\s]+
来匹配文本,它匹配单词字符和空格,但无法匹配标点符号和其他字符。我本可以使用 .*?
,它也能正常工作。但是,我使用了以下结构,它匹配相同,但性能更好:
( #text:= any char except "{", or a "{" not followed by /commandname
[^{]*+
(?>\{(?!/?[{}])[^{]*)*?
)
最后,我使用 </code> 匹配结束标签,这是对组 1 中匹配的文本(开始标签名称)的反向引用:</p>
<pre><code>\{/}
假设:
- 属性在引号中没有右括号,例如
"te}xt"
可能会导致它中断。