我需要扩展一个目前用正则表达式

时间:2016-07-22 16:56:12

标签: regex

我在C#中进行一些文本处理。我需要从文本字符串中提取元素:

pre-text[var1|2|3]in-text[vara|b|c]post-text

稍后在处理中,我将这些括号中的表达式替换为数据存储中的值。一般表格最好用正则表达式表示(为清楚起见,添加了两个换行符):

\[(?<var>[^]|]+)\]|
\[(?<var>[^]|]+)\|(?<fmt>[^]|]+)\]|
\[(?<var>[^]|]+)\|(?<fmt>[^]|]+)\|(?<txt>[^]|]+)\]

因此,如果我想从数据库中包含日期并对其进行格式化,我可以创建一个模板,例如:

We are looking forward to seeing you at your next clinic visit on
[$event_datetime|D] at [$event_datetime|h:mm tt] at the Center.

经过简单的处理后,这就变成了:

We are looking forward to seeing you at your next clinic visit on 
Tuesday, June 30, 2015 at 5:30 PM at the Center

应用正则表达式可以获得我需要的所有定位,变量和格式信息。

我现在想做的是能够在变量引用中嵌套(单个级别)另一个变量引用。例如,如果我想为“field_001”创建数据引用,我目前需要引用类似的内容:

[field_001]

相反,我希望能够指定:

[field_[$occurrence|000]]

我保留了使用正则表达式进行解析所产生的所有匹配,然后在数据可用后执行替换。有了这个新功能,我希望我需要保留两组匹配,首先执行嵌套替换,然后执行外部替换。

所以,从一个字符串开始,如:

This string is your [field_[$occurrence|000]]!

所以第一遍,替换所有内部数据引用将给我,(假设“$ occurrence”的值为1)一个字符串:“001”,然后我将替换为外部变量引用,之后在哪一点上,我将查找新的变量名称“field_001”以获得它的值。

第二次替换会给我,假设“field_001”的值是“string”:

This string is your string!

但是我无法提出所需的正则表达式。我还怀疑我目前的正则表达式并不是最优的,并且很高兴听到如何改进它。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

对于这种情况,就像你说的那样,如果进行嵌套,最好做到 内到外的替代。

这需要坐在一个循环中,每个传递开始 从修改后的字符串开始处理。

PHP的一个例子是:

$strSrc = " ... ";
$found = 1;

while ( $found )
{
    $found = 0;
    $strSrc = preg_replace_callback('the regex',
         function( $matches )
         {
             $found = 1;
             $repl = "initial string replacement";
             if ( $matches["var"] )
             {
                 // add to $repl
             }
             if ( $matches["fmt"] )
             {
                 // add to $repl
             }
             if ( $matches["txt"] )
             {
                 // add to $repl
             }
             return $repl;
         },
         $strSrc
     );
}

伴随的原始正则表达式将是:

\[(?<var>[^\[\]|]+)(?:\|(?<fmt>[^\[\]|]+)(?:\|(?<txt>[^\[\]|]+))?)?\]

Stringed:

'~\[(?<var>[^\[\]|]+)(?:\|(?<fmt>[^\[\]|]+)(?:\|(?<txt>[^\[\]|]+))?)?\]~'  

Formated / Expanded:

 \[
 (?<var> [^\[\]|]+ )           # (1), Var
 (?:                           # Optional fmt
      \|
      (?<fmt> [^\[\]|]+ )           # (2), Fmt
      (?:                           # Optional txt
           \|
           (?<txt> [^\[\]|]+ )           # (3), Txt
      )?
 )?
 \]

<强> 修改
要允许转义括号,请使用此 -

原始:

\[(?<var>[^\[\]\\|]*(?:\\.[^\[\]\\|]*)*)(?:\|(?<fmt>[^\[\]\\|]*(?:\\.[^\[\]\\|]*)*)(?:\|(?<txt>[^\[\]\\|]*(?:\\.[^\[\]\\|]*)*))?)?\]

Stringed:

'~\[(?<var>[^\[\]\\\|]*(?:\\\.[^\[\]\\\|]*)*)(?:\|(?<fmt>[^\[\]\\\|]*(?:\\\.[^\[\]\\\|]*)*)(?:\|(?<txt>[^\[\]\\\|]*(?:\\\.[^\[\]\\\|]*)*))?)?\]~'

格式化

 \[
 (?<var>                       # (1 start), Var
      [^\[\]\\|]* 
      (?: \\ . [^\[\]\\|]* )*
 )                             # (1 end)
 (?:                           # Optional fmt
      \|
      (?<fmt>                       # (2 start), Fmt
           [^\[\]\\|]* 
           (?: \\ . [^\[\]\\|]* )*
      )                             # (2 end)
      (?:                           # Optional txt
           \|
           (?<txt>                       # (3 start), Txt
                [^\[\]\\|]* 
                (?: \\ . [^\[\]\\|]* )*
           )                             # (3 end)
      )?
 )?
 \]