wincao 发表于 2024-8-20 08:18

在使用正则表达式的疑惑

本帖最后由 wincao 于 2024-8-20 09:39 编辑

在Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.11.0环境下,输出结果是标点全部被替换了。哪里出问题了呢?

       private void test()
       {
         string text = "这是一个测试。这里有一些内容(包括括号内的内容,不要替换这些。)以及一些,逗号和、符号;需要被替换。";

         // 正则表达式解释:
         // [。,] 匹配中文句号或逗号
         // (?<!\(.*?[^()]) 负向后瞻,确保字符前面没有括号
         // (?![^()]*\)) 负向先行,确保字符后面没有闭合的括号
         string pattern = @"(?<!\(.*?[^()])[。,](?![^()]*\))";

         // 替换匹配的逗号和句号为空格
         string result = Regex.Replace(text, pattern, " ");

         Console.WriteLine(result);
         // 期望输出: "这是一个测试这里有一些内容(包括括号内的内容,不要替换这些。)以及一些 逗号和、符号;需要被替换 "
       }

ygq170063 发表于 2024-8-20 08:44

private void test()
{
    string text = "这是一个测试。这里有一些内容(包括括号内的内容,不要替换这些。)以及一些,逗号和、符号;需要被替换。";

    // 使用正则表达式提取括号内的内容
    string patternBrackets = @"(.*?)";
    var matches = Regex.Matches(text, patternBrackets);
   
    // 替换括号内的内容为占位符
    int index = 0;
    foreach (Match match in matches)
    {
      text = text.Replace(match.Value, $"__PLACEHOLDER_{index++}__");
    }
   
    // 替换剩余内容中的标点符号
    string patternPunctuation = "[。,]";
    text = Regex.Replace(text, patternPunctuation, " ");
   
    // 还原括号内的内容
    index = 0;
    foreach (Match match in matches)
    {
      text = text.Replace($"__PLACEHOLDER_{index++}__", match.Value);
    }

    Console.WriteLine(text);
    // 输出: "这是一个测试这里有一些内容(包括括号内的内容,不要替换这些。)以及一些 逗号和、符号;需要被替换 "
}

nzkboy 发表于 2024-8-20 09:13

正则表达式,太高级,一直看不懂

Dropless 发表于 2024-8-20 09:34

一楼的思路是对的, 一般这种可以先把对象外的临时替换掉,之后再恢复.

不过从你的正则本身来看, 应该是混淆了全角与半角括号
string pattern = @"(?<!\(.*?[^()])[。,](?![^()]*\))";

应当是
string pattern = @"(?<!(.*?[^()])[。,](?![^()]*))";

不过这个正则本身还是有问题, 使用该正则的输出为:
    这是一个测试 这里有一些内容(包括括号内的内容,不要替换这些。)以及一些,逗号和、符号;需要被替换。

括号里的没有受影响了, 但是后面 "以及一些,逗号" 中的逗号没有被替换掉. 因为这个逗号前的文本也是符合(.*?[^()]这个模式的

改了一下, 测试文本额外添加了一对括号

using System.Text.RegularExpressions;
string text = "这是一个测试。这里有一些内容(包括括号内的内容,不要替换这些。)以及(包括括号内的内容,不要替换这些。)一些,逗号和、符号;需要被替换。";

string pattern = @"(?<!([^()]*)[。,](?![^()]*))";

// 替换匹配的逗号和句号为空格
string result = Regex.Replace(text, pattern, " ");

Console.WriteLine(result);
// 期望输出: 这是一个测试 这里有一些内容(包括括号内的内容,不要替换这些。)以及(包括括号内的内容,不要替换这些。)一些 逗号和、符号;需要被替换


不过还是开头那句话, 这种一般按一楼的思路来要更好, 复杂的正则总会有各种 edge case 难以考虑到, 而且可读性差
页: [1]
查看完整版本: 在使用正则表达式的疑惑