English 中文(简体)
正则表达式:如何获取标签#[这里的一些文本]内的所有内容
原标题:
  • 时间:2009-02-02 08:44:08
  •  标签:

我正在开发我们产品的一个简单的令牌替换功能。我几乎解决了所有问题,但我忘了一件事。令牌必须支持属性,而属性也可以是一个令牌。这是一个更大的项目的一部分。希望你能帮忙。

开始标签是 "**#[**",结束标签是 "**]**"。例如,#[名字],#[姓氏],#[年龄,当为零时=“未公开”]。

现在我正在使用这个表达式"#[[^]]+]"。我已经使用这个工作了,但它在这个输入上失败了:

blah blah text here...
**#[IsFreeShipping, WhenTrue="<img src= /images/fw_freeshipping.gif />
<a href= http://www.hellowebsite.net/freeshipping.aspx >$[FreeShipping]</a>"]**
blah blah text here also...

它失败是因为它遇到了第一个],它就停在那里了。 它返回:

*#[IsFreeShipping, WhenTrue="<img src= /images/fw_freeshipping.gif />
<a href= http://www.hellowebsite.net/freeshipping.aspx >$[Product_FreeShipping]*

我的期望结果应该是:

*#[IsFreeShipping, WhenTrue="<img src= /images/fw_freeshipping.gif />
<a href= http://www.hellowebsite.net/freeshipping.aspx >$[FreeShipping]</a>"]*
问题回答

您的正则表达式完全匹配您声明的条件,即以左方括号开头,并匹配至第一个右方括号。

如果您想匹配嵌套的方括号,您需要明确指定什么时候嵌套是有效的。例如,您可以说当方括号被引号包围时可以嵌套。

这对于正则表达式来说有些接近边缘,因为它取决于上下文,但仍然...

#[(](?=")|[^]])+]

应该这样做。

这个想法是要指出,如果方括号后面跟着双引号作为属性结束的一部分,那么方括号可以成为已解析内容的一部分。

如果同样的方括号在属性的任何地方,那将会更加困难…


The advantage with lookahead expression is that you can specify a regexp with a non-fixed match length.
So if the attribute closing square bracket is not followed by a double quote, but rather by another known expression, you just update the lookahead part:

#[(](?=</a>")|[^]])+]

只匹配第二个闭方括号,因为第一个后面跟着</a>"

当然,任何一种贪婪表达式(.*])都行不通,因为它不会匹配第二个右方括号,而是匹配最后一个右方括号。(这意味着,如果中间有多个],则会解析该表达式。)

当我之前处理过类似的东西时,我会从最内层的可匹配表达式开始评估,然后再到更大的字符串。

在这种情况下,您的正则表达式应该尝试在评估包含if子句的更大令牌之前替换 $[FreeShipping] 为其值。

也许你可以想办法在没有$前缀的令牌之前替换掉像$[FreeShipping]这样的价值令牌。

这大致但不完全准确。

多遍编译器与单遍编译器。

用一个正则表达式写这个不一定比循环几个简单的正则表达式更快。所有正则表达式都是抽象的字符串解析工具。

如果您只期望任何给定输入中有一个匹配项,您可以简单地允许贪婪匹配:

/#[.*]/

如果你期望有多个,那么你就有问题,因为你不再有常规的文本。你需要以某种方式跳出内部括号。

正则表达式是一个深奥的主题——很可能有人有更好的解决方案。

我很想知道我是否错了,但如果我记得正确的话,您无法使用正则表达式来完成此操作。这对我来说看起来像是Dyck语言,您需要一个下推自动机来接受表达式。但我必须承认,对于像Perl提供的扩展形式的正则表达式,我不太确定是否适用。

你所提供的例子可以编写一个正则表达式,但通常是失败的。单个正则表达式无法处理任意嵌套表达式。

你的例子说明你的DSL已经有了if条件。不久它可能会发展成一个图灵完备的语言。

你为什么不使用现有的模板语言,比如Django模板语言呢?

你的例子:

blah blah text here... #[IsFreeShipping, 
WhenTrue="<img src= /images/fw_freeshipping.gif />
<a href= http://www.hellowebsite.net/freeshipping.aspx >$[FreeShipping]</a>"]
blah blah text here also...

使用Django模板语言:

blah blah text here... {% if IsFreeShipping %}
<img src= /images/fw_freeshipping.gif />
<a href= http://www.hellowebsite.net/freeshipping.aspx >{{ FreeShipping }}</a>
{% endif %} blah blah text here also...

这适用于您的样品:

#[(?:[^]$]+|$(?![)|$[[^[]]*])*]

它假定内部方括号本身不能包含方括号。如果内部标记也可以包含标记,则可能没有办法。一些正则表达式风格可以处理递归结构,但得到的正则表达式甚至在正则表达式标准中也很难看。 :D

此正则表达式仅在紧随其后为开方括号时将 $ 视为特殊字符。如果想要禁止其在其他情况下使用,可以删除第二个选择项:|$(?![)





相关问题
热门标签