使用正则表达式替换引号外的空白

本文关键字:空白 正则表达式 替换 | 更新日期: 2023-09-27 17:57:44

使用C#,我需要准备一个搜索文本,以便使用LIKE命令在SQL Server数据库中进行搜索,将引号外的所有空白替换为%字符。示例:

输入:

my "search text"

输出:

%my%search text%

如有任何帮助,我们将不胜感激。在替换文本之前,我可以处理带有奇数引号的输入字符串。

使用正则表达式替换引号外的空白

不要使用RegEx,而是在每个字符上使用一个简单的状态机循环,注意引号是"in"还是"out",并且只在处于"out"状态时替换空格。

如果使用正则表达式,那么如果您确定所有引号都正确平衡,并且字符串中没有转义引号('"),则可以执行此操作(也可以考虑这些引号,但这会使正则表达式更加复杂)。

resultString = Regex.Replace(subjectString, 
    @"[' ]       # Match a space (brackets for legibility)
    (?=          # Assert that the string after the current position matches...
     [^""]*      # any non-quote characters
     (?:         # followed by...
      ""[^""]*   # one quote, followed by 0+ non-quotes
      ""[^""]*   # a second quote and 0+ non-quotes
     )*          # any number of times, ensuring an even number of quotes
    $            # until the end of the string
    )            # End of lookahead", 
    "%", RegexOptions.IgnorePatternWhitespace);

这将检查字符串的其余部分,以便在当前空格字符后断言偶数个引号。lookahead的优点(感谢AlanMoore!)是它比lookbacking更具可移植性(除了.NET和其他一些正则表达式之外,大多数正则表达式风格都不支持lookbacking断言中的无限重复)。它也可能更快。

涉及后备的原始解决方案如下:

resultString = Regex.Replace(subjectString, 
    @"(?<=       # Assert that the string up to the current position matches...
    ^            # from the start of the string
     [^""]*      # any non-quote characters
     (?:         # followed by...
      ""[^""]*   # one quote, followed by 0+ non-quotes
      ""[^""]*   # a second quote and 0+ non-quotes
     )*          # any number of times, ensuring an even number of quotes
    )            # End of lookbehind
    [ ]          # Match a space (brackets for legibility)", 
    "%", RegexOptions.IgnorePatternWhitespace);

如果双引号没有以某种方式转义,那么下面是另一种可能性。可能不如某些方法高效(当然也不如Tim的正则表达式酷),但当下一个人查看代码时,这可能是可以理解的。它将字符串拆分为双引号,然后在值之间循环。奇数条目是引号外的部分,偶数条目是引号内的部分。

  string value = "'"first'" some text '"other in quotes'" out of them '"in them'"";
  string[] sets = value.Split(''"' );
  StringBuilder newvalue = new StringBuilder("%");
  for (int i = 0; i < sets.Length; i++) {
     if ( i % 2 == 0 )
        // even ones are outside quotes
        newvalue.Append( sets[i].Replace( ' ', '%' ));
     else
        // and the odd ones are in quotes
        newvalue.Append( "'"" + sets[i] + "'"" );
  }
  // final %
  newvalue.Append("%");

看起来您还想删除引号,并在搜索字符串的开头和结尾添加一个%。试试这个:

string s0 = @"my ""search text""";
Regex re = new Regex(@"(?x)
    (?:
       (?<term>[^'s""]+)
     |
       ""(?<term>[^""]+)""
    )
    (?:'s+|$)");
string s1 = @"%" + re.Replace(s0, @"${term}%");
Console.WriteLine(s1);

输出:

%my%search text%

会做这样的事情:

 private static string RemoveUnquotedWhiteSpaces(string text)
 {    
    string result = String.Empty;
    var parts = text.Split('"');
    for(int i = 0; i < parts.Length; i++)
    {
       if (i % 2 == 0) result += Regex.Replace(parts[i], " ", "");
       else result += String.Format("'"{0}'"", parts[i]);
    }
    return result
  }