【问题标题】:RegEx replacement between "arbitrary" delimiters“任意”分隔符之间的正则表达式替换
【发布时间】:2012-11-03 16:08:01
【问题描述】:

我在替换“任意”分隔符之间的部分文本文件时遇到了一些问题。

这是我想做的:我有如下标记:

//   [ADX START] ANYTHING //   [ADX END] 

<!--    [ADX START] --> ANYTHING <!-- [ADX END]  -->

/*   
 [ADX START] */  ANYTHING /*  [ADX END]        */

所以,这些是不同的评论风格,我想抓住开头的 [ADX START](包括周围的评论),然后是中间的文本,最后是最后的 [ADX END]。

因此,我给它一个这样的文本文件:

test.php:
<?php
BEFORE    
// [ADX START]
REMOVEME
// [ADX END]
AFTER

test.css:
BEFORE    
/* [ADX START]*/
REMOVEME
/*[ADX END] */
AFTER

变成:

test.php:
<?php
BEFORE    
AFTER

test.css:
BEFORE    
AFTER

等等。如您所见,注释样式和分隔符之间可以有任意数量的空格(或没有空格)。

所以,到目前为止,我想出了以下几点:

string newFileContent = Regex.Matches(fileContent, "(\\[ADX START\\].*\\[ADX END\\])", RegexOptions.IgnoreCase);

但是,这没有任何作用。我认为让我绊倒的是括号等;此外,我希望能够简单地插入不同的注释样式,例如 #、//、/**/ 等;

任何指向正确方向的指针都将不胜感激。

【问题讨论】:

  • 是否可以对分隔符使用更统一的注释语法?
  • 您好 Asad,感谢您的评论。我不完全确定你的意思。但是,我需要的只是一个正则表达式,它允许我“插入”两个任意分隔符,然后将它们替换掉并替换它们之间的所有内容(包括分隔符本身)。
  • 对于这种不规则的输入,我不认为 Regex 是您的最佳选择。为此编写您自己的解析器。
  • 我考虑过这一点,因为使用解析器执行此操作并不难。但是,解析器将无法忽略分隔符和注释之间的空白量。所以我必须考虑“// DELIMITER”和“//(更多空白)DELIMITER”和“//(更多空白)DELIMITER”等;使用结束分隔符的可能性数量的力量(更不用说可能的换行符)。或者我强制它 必须 是注释和分隔符之间的一个空格。

标签: c# .net regex delimiter replace


【解决方案1】:

像这样使用单行选项和正则表达式

string strRegex =@"(\/\/|\/\*).*?\[ADX START\].*?\[ADX END\]\s*(\*\/)?";
                         ^                      ^                 ^
                         |                      |                 |->match */ 0 or 1 time
                         |                      |
                         |                      |->match lazily till the first ADX END
                         |->match // or /*
string s=Regex.Replace(fileContent,strRegex,"",RegexOptions.Singleline);//replace it

【讨论】:

  • 嗨 Fake.It.Til.U.Make.It,非常感谢您的出色解释以及正则表达式!我开始了解它是如何工作的,但是,当使用这个正则表达式时,输出字符串与输入字符串相同。我也喜欢它结合两种评论风格的方式,所以我将能够复制“OR”运算符以获得更多风格。您是否会知道,为什么它不起作用?我的输入如下: string contentBefore = @"
  • 天哪,这真是太棒了 Fake.It.Til.U.Make.It!非常感谢。我现在理解了最终的“匹配 0 或 1”。但是,不知何故,它与最终的不匹配。例如 INPUT: "\r\n
  • 你是个超级巨星,伙计!完美运行,我什至可以添加另一种评论风格: 如下: "(\/\/|\/*|)?" ... 再一次非常感谢你! :-)
  • @TEST 正则表达式非常简单。;)
【解决方案2】:

.* 通常不会跨换行符匹配;你需要RegexOptions.Singleline 才能做到这一点。但是,您应该使用.*? 来获得非贪婪匹配。此外,您的正则表达式不会尝试捕获[ADX START] 之前或[ADX END] 之后的部分行。最后,您使用的是Regex.Matches,而不是Regex.Replace,因此它实际上并没有修改任何内容。

试试这个:

Regex commentRegex = new Regex(@"^.*?\[ADX START\].*?\[ADX END\].?$", RegexOptions.IgnoreCase | RegexOptions.Singleline);
string newFileContent = commentRegex.Replace(fileContent);

【讨论】:

  • 感谢您的回答 Barmar,我刚开始使用 Regex,因此仍然遇到一些问题。我刚刚尝试了您的正则表达式,运行时错误告诉我没有足够的括号。我试图把它放在最后的 ".?$" 之前,但它没有产生预期的结果 - 无论如何,非常感谢你的正则表达式,我会把它拆开并尝试理解它。
  • 开头附近的( 不需要,我只是去掉了它。现在试试。注意:我不是 C# 程序员,我可能在语法的某些细节上弄错了。
  • @Barmar 使用 \ 而不是 \\ 如果您使用的是逐字字符串,即 @""
  • @Fake.It.Til.U.Make.It Thx,已修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多