Perl中的递归正则表达式

DEg*_*rov 0 regex recursion perl

我有这样的字符串:

| Released    = {{start-date|June 14, 1972}}
| Released    = {{Start date|1973|03|01|df=y}} 
Run Code Online (Sandbox Code Playgroud)

我想替换所有| 在{{}}内使用^

| Released    = {{start-date^June 14, 1972}}
| Released    = {{Start date^1973^03^01^df=y}} 
Run Code Online (Sandbox Code Playgroud)

我不能使用子串替换,因为有| {{}}之外的符号,必须保持不变.而且因为我不确切知道{{}}中的字符串有多少部分,所以我不能使用类似的字符串s/{{(.+?)\|(.+?)}}/{{$1^$2}}/.

我想我需要在这里使用某种递归?

Qta*_*tax 5

简单的解决方案:

s/\|(?=[^{}\n]*}})/^/g
Run Code Online (Sandbox Code Playgroud)

更简单的解决方案,但在许多情况下可能会破坏:

s/(?!^)\|/^/gm
Run Code Online (Sandbox Code Playgroud)

这是一个更强大的正则表达式:

s/(?:\G(?!^)(?:(?>[^|]*?}})(?>.*?{{))*|^(?>.*?{{))(?>[^|]*?(?=}}|\|))\K\|(?=.*?}})/^/gs;
Run Code Online (Sandbox Code Playgroud)

评论:

s/
(?:
  \G(?!^)                       # inside of a {{}} tag
  (?: (?>[^|]*?}}) (?>.*?{{) )* # read till we find a | in another tag if none in current
  |
  ^(?>.*?{{)                    # outside of tag, parse till in
)
(?> [^|]*? (?=}}|\|) )          # eat till a | or end of tag
\K                              # don't include stuff to the left of \K in the match
\|                              # the |
(?=.*?}})                       # just to make sure the tag is closed
/^/gsx;
Run Code Online (Sandbox Code Playgroud)

输入:

|}}
| Re|eased    = {{start-date|June 14^, {|1972}|x}}
| Released    = {{Start date}|1973|03|01}|df=y|}}
| || {{|}} {{ |
Run Code Online (Sandbox Code Playgroud)

输出:

|}}
| Re|eased    = {{start-date^June 14^, {^1972}^x}}
| Released    = {{Start date}^1973^03^01}^df=y^}}
| || {{^}} {{ |
Run Code Online (Sandbox Code Playgroud)

示例:http://ideone.com/fbY2W