2011-09-09 30 views
0

我意识到之前曾经有类似的问题,但我似乎无法解决我正在尝试做的事情,所以请不要只是认为这是一个骗局。否定正则表达式中的字符串

我在风格{block:string}contents{/block:string}一个字符串,它可以与{block:([a-z_-\s]+)}.*{/block:\1}

很容易被匹配什么我想要做的就是修改内。*的一部分,以便它匹配具有任何字符串它们之间的{block:[a-z_-\s]+},即所有{block} {/ block}里面的{block}都不应该匹配。

谢谢!

回答

2

尝试

{block:([a-z_-\s]+)}[^{]*(?!{block:([a-z_-\s]+)}.*{\block:\2})[^}]*{/block:\1} 

我在正则表达式姿色平平,但负先行所界定的[^ {] *和[^}] *语句应该保留匹配标签免费。

+0

不行的话恐怕:( – Meep3D

+0

是它未能匹配或PHP的正则表达式给你一个错误? –

+0

不匹配任何东西:( – Meep3D

2

压缩:m~\{block:([a-z\s_-]+)\}(?:(?!\{/?block:\1\}).)*\{/block:\1\}~xs

实施例中的Perl:

$_ = '{block:string}conte{block:string}nts{/block:string}{/block:string}'; 

if (m~ # match operator 

     \{block: ([a-z\s_-]+) \} # opening block structure and capt grp 1 

     (?:      # begin non capt grp 
      (?! \{/?block: \1 \})  # negative lookahead, don't want backreffed 
             # open or closed block struct  
      .       # ok, grab this character 
     )*       # end group, do 0 or more times (greedy) 

     \{/block: \1 \}   # closing block structure matching grp 1 

    ~xs) # modifiers: expanded, include newlines 

{ 
    print "matched '$&'\n"; 
} 

输出:
匹配 '{块:串} NTS {/块:串}'

+0

+1。以下是PHP版本:** [demo](http://ideone.com/TY8WV)** –

+0

感谢Alan。应该咬紧牙关,一直在推迟PHP long – sln

1
<?php 
$ptn = "%(?:{block:[a-z_\s-]+})(?![^}]*?{block:).*?{/block:[a-z_\s-]+}%"; 
$str = "... your content here ..."; 
preg_match_all($ptn, $str, $matches); 
print_r($matches); 
?> 

例如:

$str = "{block:string}test2{/block:string} {block:string}contents{block:string}{block:string}test3{/block:string}{/block:string}{/block:string} sdf "; 

将产生:

Array 
(
[0] => Array 
    (
     [0] => {block:string}test2{/block:string} 
     [1] => {block:string}test3{/block:string} 
    ) 
) 
+0

我不知道他的backref是否很重要,但是你的正则表达式匹配'“{block:stringa} nts {/ block:string}”' – sln

+0

我假设(也许不正确)返回引用是尝试在嵌套时匹配标签,你可能是正确的:{block:abc} content {/ block:def}'可能存在并且是无效的,如果是这样,现在他知道它需要被修复。 –