我在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!
但是我无法提出所需的正则表达式。我还怀疑我目前的正则表达式并不是最优的,并且很高兴听到如何改进它。
有什么想法吗?
答案 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)
)?
)?
\]