正则表达式:如何获取标签内的所有内容#[SOME TEXT HERE]

时间:2009-02-02 08:44:09

标签: regex

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

开头标记为"**#[**",结束标记为"**]**"。比如,#[FirstName],#[LastName],#[Age,WhenZero =“Undisclosed”]。

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

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>"]*

7 个答案:

答案 0 :(得分:1)

这是正则表达式的一个小边界线,因为它取决于上下文,但仍然......

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

应该这样做。

这个想法是提到一个结束方括号可以是解析内容的一部分,如果后跟双引号,则作为属性结尾的一部分。

如果属性中的任何位置都有相同的方括号,那将会更加困难......


超前表达式的优点是您可以指定具有非固定匹配长度的正则表达式 因此,如果关闭方括号的属性后面没有双引号,而是另一个已知表达式,则只需更新前瞻部分:

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

将仅匹配第二个右方括号,因为第一个后跟</a>"

当然,任何类型的贪婪表达式(.*])都不起作用,因为它与第二个结束方括号不匹配,而最后一个。 (如果有更多的中间],则表示将对其进行解析。)

答案 1 :(得分:1)

您的正则表达式与您所声明的条件完全匹配:从一个方括号开始,并将所有内容与第一个结束方括号相匹配。

如果要匹配嵌套的方括号,则需要准确指定嵌套时的有效内容。例如,你可以说方括号可以用引号括起来嵌套。

答案 2 :(得分:0)

在我从最内部的最匹配表达式进行评估之前,我已经完成了这样的事情,然后再逐步使用更大的字符串。

在这种情况下,你的正则表达式可能会在评估包含if子句的较大标记之前尝试用它的值替换$ [FreeShipping]。

也许你可以找到一种方法来替换价值代币,就像$ [FreeShipping]之前没有$前置代码的那样

这大致但不完全是

http://en.wikipedia.org/wiki/Multi-pass_compilerhttp://en.wikipedia.org/wiki/One-pass_compiler

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

答案 3 :(得分:0)

如果您只想在任何给定输入中进行一场比赛,那么您可以简单地允许进行贪婪的比赛:

/#\[.*\]/

如果您期望倍数,则会出现问题,因为您不再有常规文字。你需要以某种方式逃避内部括号。

(正则表达式是一个深层次的主题 - 很可能有人有更好的解决方案)

答案 4 :(得分:0)

我有兴趣了解我是否错了,但如果我没记错,你不能用正则表达式来做。对我来说这看起来像Dyck语言,你需要一个下推自动机来接受表达式。但我必须承认,我不太确定这是否适用于Perl提供的扩展形式的正则表达式。

答案 5 :(得分:0)

可以为您给出的示例编写正则表达式,但一般情况下它会失败。单个正则表达式不适用于任意嵌套表达式。

您的示例显示您的DSL已经具有“if”条件。不久之后,它可以演变为图灵完整的语言。

为什么不使用现有的模板语言,例如Django template language

你的例子:

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...

答案 6 :(得分:0)

这适用于您的样本:

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

它假定内方括号本身不能包含方括号。如果内部令牌也可以包含令牌,那么你可能运气不好。一些正则表达式的风格可以处理递归结构,但即使通过正则表达式标准,生成的正则表达式仍然是可怕的。 :d

Tis正则表达式只会将'$'视为特殊的,只要它后面是一个开头的方括号。如果您不想禁用它,请删除第二个替代方法:|\$(?!\[)