2009-01-22 51 views
2

鉴于$displayHeight = "800";,用int值y_res替换800上的任何数字。C#正则表达式替换意外行为

resultString = Regex.Replace(
    im_cfg_contents, 
    @"\$displayHeight[\s]*=[\s]*""(.*)"";", 
    Convert.ToString(y_res)); 

在Python中,我会使用re.sub,它会工作。在.NET中,它将替换整个行,而不是匹配的组。

什么是快速修复?

回答

2

建立在已发布的几个答案上。零宽度断言允许您执行正则表达式匹配,而不会将这些字符放在匹配中。通过将字符串的第一部分放在一个组中,我们将它与要替换的数字分开。然后,通过在该组中使用零宽度lookbehind断言,我们允许正常表达式正常进行,但忽略匹配中该组中的字符。同样,我们已将字符串的最后一部分放在一个组中,并使用了零宽度的前瞻断言。 Grouping Constructs on MSDN显示组以及断言。

resultString = Regex.Replace(
    im_cfg_contents, 
    @"(?<=\$displayHeight[\s]*=[\s]*"")(.*)(?="";)", 
    Convert.ToString(y_res)); 

另一种方法是使用下面的代码。对正则表达式的修改只是将第一部分放在一个组中,将最后一部分放入组中。然后在替换字符串中,我们添加回第一和第三组。不像第一种方法那么好,但不如写出$ displayHeight部分那么糟糕。 Substitutions on MSDN显示$字符是如何工作的。

resultString = Regex.Replace(
    im_cfg_contents, 
    @"(\$displayHeight[\s]*=[\s]*"")(.*)("";)", 
    "${1}" + Convert.ToString(y_res) + "${3}"); 
0

试试这个:

resultString = Regex.Replace(
    im_cfg_contents, 
    @"\$displayHeight[\s]*=[\s]*""(.*)"";", 
    @"\$displayHeight = """ + Convert.ToString(y_res) + @""";"); 
+0

我同意,这将工作,但该死的这是丑陋的。 – 2009-01-22 15:18:24

0

你也可以试试这个,但我觉得它比我的其他方法慢一点:

resultString = Regex.Replace(
    im_cfg_contents, 
    "(?<=\\$displayHeight[\\s]*=[\\s]*\").*(?=\";)", 
    Convert.ToString(y_res)); 
0

它取代了整个字符串,因为你已经匹配整个字符串 - 没有任何关于此语句的信息告诉C#只替换匹配的组,它将确定找到并存储匹配的组,但它仍然匹配整个字符串。

你可以改变你的替代品来:

@"\$displayHeight = """ + Convert.ToString(y_res) + @""";" 

..或者你可以改变你的模式,只是匹配的数字,即:

@"[0-9]+" 

..或者你可以看到,如果C#正则表达式支持lookarounds(我不确定它是否正确)并相应地改变你的匹配。

+0

没有领先/在替代品字符串 – 2009-01-22 15:34:20

0

检查这种模式出来

(?<=(\$displayHeight\s*=\s*"))\d+(?=";) 

字约 “lookaround”。