使用正则表达式(.net 和 C#)识别行尾
Posted
技术标签:
【中文标题】使用正则表达式(.net 和 C#)识别行尾【英文标题】:Identify line end with Regex (.net and C#) 【发布时间】:2021-12-08 08:54:19 【问题描述】:(遇到同样情况的朋友,请注意这个问题可能是.net和C#指定的。见下面Wiktor的回答。)
在问这个问题之前,我已经阅读了许多相关问题(包括:Match linebreaks - \n or \r\n?),但这些答案都没有奏效。
就我而言,我想删除某些代码文件中的所有 //cmets。为了处理 Mac、Unix、Windows 中的文件,我需要一些东西来匹配 // 和 /r、或 /n 或 /r/n 之间的文本。
这里是代码文件的测试内容:
var text = "int rn = 0; //comment1.0\r\n" +
"int r = 0; //comment2.\r" +
"int n = 0; //comment3.\n" +
"end";
var txt = RemoveLineEndComment();
这里是正则表达式(如果你不是 C charper,请只关注正则表达式):
public static class CommentRemover
private static readonly Regex RegexRemoveLineEndComment =
new(@"\/\/.*$", RegexOptions.Multiline);
public static string RemoveLineEndComment(this string text)
var t = RegexRemoveLineEndComment.Match(text).Value;
return RegexRemoveLineEndComment.Replace(text, string.Empty);
我需要的是 txt = "int rn = 0; \r\nint r = 0; \rint n = 0; \nend"。 以下是正则表达式和相应的结果:
//.*$ => txt="int rn = 0; \nint r = 0; \nend"(缺少int n = 0)
//.*(?=\r\n) => txt="int rn = 0; \r\nint r = 0; //comment2.\rint n = 0; //comment3.\nend" (留下评论2和3)
//.*(?=\r?\n?) => txt="int rn = 0; \nint r = 0; \nend"(缺少int n = 0)
//.*(?=(\r\n|\r|\n)) => txt="int rn = 0; \nint r = 0; \nend" (缺少int n = 0)
//.*(?=[\r\n|\r|\n]) => txt="int rn = 0; \nint r = 0; \nend" (缺少int n = 0) ...
\r 似乎有问题,无法识别。 如果我只使用 \r\n,则正则表达式 "//.*(?=\r\n)" 适用于下面的测试内容:
var text = "int rn = 0; //comment1.0\r\n" +
"int r = 0; //comment2.\r\n" +
"int n = 0; //comment3.\r\n" +
"end";
有人帮帮我吗?感谢您的帮助。
【问题讨论】:
请包含语言标签。 @Barmar 抱歉,我认为这是纯正则表达式问题。但正如 Wiktor 在下面提到的,这可能是一个 .net 问题。如果是这样,我会包括语言标签。 :) 您正在处理的代码是否可能包含例如包含//
序列并且不应被视为cmets的字符串文字?
@Damien_The_Unbeliever 否。不在此测试代码中。但它确实发生在我的旧版本中(那个版本中没有使用正则表达式)。可能有类似 text = "//hello" 和 //"hello" 的代码。我对正则表达式不熟悉了,以后会处理这些复杂的情况:)
【参考方案1】:
在 .NET 中,.
模式匹配回车 (CR) 字符。它匹配除 LF 字符之外的任何字符。
请注意,没有选项或修饰符可以重新定义此 .
行为。
因此,您可以使用
var RegexRemoveLineEndComment = new Regex(@"//[^\r\n]*", RegexOptions.Multiline);
请参阅C# demo。
如果您还想删除//
之前的空格,请在模式开始处添加\s*
(任何空格)或[\pZs\t]*
(水平空格)。
【讨论】:
感谢您的帮助!但是......奇怪的是,我将您的代码从链接复制到一个新项目中,我又得到了“int rn = 0; \nint r = 0; \nend”(int n = 0 is missing)。 \r 仍然没有被识别,这真的很奇怪。版本之间的差异是否重要? (我正在使用 .net5)我想只用 \r 尝试一些东西,看看是否还有其他线索。再次感谢。 @cheny 由于我没有你的代码,我无法提供更多帮助。我刚刚注意到//[^\r\n]*
regex 不需要RegexOptions.Multiline
选项,可以去掉。
啊!终于,我知道到底发生了什么。我确实得到了 txt="int rn = 0; \r\nint r = 0; \rint n = 0; \nend" 的结果,但是当我使用 Console.WriteLine(txt) 时,发生了一些棘手的事情! “\r\n”的意思是“回到当前行的开头,然后下一行,在新的一行打印下面的字母”,而单独的“\r”的意思是“回到当前行的开头,并在当前行打印以下字母”。所以,“int r = 0; " 被 "int n = 0; “!我在代码中放了一个临时参数,发现了。它发生在控制台和文本区域组件中。
再次非常感谢。您将 .NET 与 \r 匹配为 .是关键。
我做到了 :) @Wiktor以上是关于使用正则表达式(.net 和 C#)识别行尾的主要内容,如果未能解决你的问题,请参考以下文章
如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#