正则表达式:在字符串开头的每个破折号前添加空格

4
var input = "---Three dashes a-b-c-d";

获取正则表达式

var output = "- - - Three dashes a-b-c-d"; 

正则表达式返回原始内容,开始处的空格将被删除。输出 => 输入

没有使用正则表达式的代码输入 => 输出

var input = "---Three dashes a-b-c-d";
var output = "";
var i = 0;
while (i < input.Length && input[i] == '-')
{
    output += "- ";
    i++;
}
output += input.Substring(i);
3个回答

3
虽然 @TedLyngmo 的解决方案可行,但在 lookbehind 模式中使用通配符效率较低。
一个更有效的方法是使用正向 lookbehind 模式来断言仅有破折号前面有匹配项:
@"(?<=^-+)"

用空格替换匹配项。

在 regex101 上,上述正则表达式运行时间为 0.2 毫秒,而 @TedLyngmo 的运行时间为 19.5 毫秒。

演示:https://regex101.com/r/6uy1K8/3

正则表达式(带有尾随空格)以删除添加的空格以恢复原始文本:

@"(?<=^(?:- )*-) "

请注意末尾的空格

将匹配项替换为空。

在 regex101 上,上述正则表达式运行时间为0.3毫秒,而@TedLyngmo的运行时间为28.1毫秒。

演示:https://regex101.com/r/fBOirM/3

请注意,所需的行为需要支持可变宽度回顾后引擎的正则表达式引擎,C#恰好具备此功能。 否则,上述正则表达式无法在不支持此类支持的平台上使用。


1
不错!我投了你一票! - Ted Lyngmo
回到原始状态在 .Net 6 中出现了问题,除非我漏掉了什么。输出没有改变。 输入 = Regex.Replace(output, @"(?<=^(?:- )*-)", ""); - MicMit
1
@MicMit,你也需要最后一个空格:@"(?<=^(?:- )*-) " - Ted Lyngmo
@Ted Lyngmo,你是对的。 - MicMit
@MicMit 太好了!现在你可以再次接受这个答案 :-) - Ted Lyngmo
1
@TedLyngmo 感谢您的编辑。我应该像您一样引用正则表达式,特别是在这种情况下确实如此。 - blhsing

1
一种方法是使用负回顾,检查破折号前面的字符是否除了破折号以外还有其他字符,并在其后加上一个空格。
@"(?<![^-].*)-"
  • (?<! - 负向先行断言开始
    • [^-] - 除了 - 以外的任何字符
    • .* - 零个或多个任何字符
  • ) - 负向先行断言结束
  • - - 一个实际的 -

全局匹配并替换为 - (破折号+空格)

演示


通过类似的方式,可以去除添加的空格以恢复原始内容:

@"(?<![^- ].*)- "

全局匹配并用-(破折号)替换。

演示


1
在C#中,您可以使用\G锚点来断言前一个匹配的结束位置或字符串的开头:
\G-

在替换时使用 - 或者你可以使用完整匹配后跟一个空格$0 查看.NET正则表达式演示C#演示
var input = "---Three dashes a-b-c-d";
string result = Regex.Replace(input, @"\G-", "- ");
Console.WriteLine(result);

输出

- - - Three dashes a-b-c-d

如果你想把它改回原来的样子,你可以再加上匹配的空格:

\G-

在替换中只使用 -

请参见另一个.NET正则表达式演示

var input = "- - - Three dashes a-b-c-d";
string result = Regex.Replace(input, @"\G- ", "-");
Console.WriteLine(result);

输出

---Three dashes a-b-c-d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接