Замените пробел вне кавычек, используя регулярное выражение - PullRequest
5 голосов
/ 24 мая 2011

Используя C #, мне нужно подготовить текст поиска для поиска в базе данных SQL Server, используя команду LIKE, заменив все пробелы вне кавычек символом%. Пример:

Введите:

my "search text"

Выход:

%my%search text%

Любая помощь будет оценена. Я могу обработать входные строки с нечетным количеством кавычек перед заменой текста.

Ответы [ 5 ]

11 голосов
/ 24 мая 2011

Вместо использования RegEx используйте простой конечный автомат - зацикливайте каждый символ, отмечая, находитесь ли вы в «или» вне кавычек, и заменяйте пробелы, только когда вы находитесь в состоянии «вне». 1002 *

6 голосов
/ 24 мая 2011

Если у вас есть для использования регулярного выражения, вы можете сделать это, если уверены, что все кавычки правильно сбалансированы, и если в строке нет экранированных кавычек (\") (этоих тоже можно учесть, но это делает регулярное выражение еще более сложным).

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 (спасибо Алану Муру!) Заключается в том, что он более переносим, ​​чем lookbehind (большинство разновидностей regex, за исключением .NET и некоторых других, не поддерживают неопределенное повторение внутри утверждений lookbehind).Это также может быть быстрее.

Исходное решение с использованием lookbehind выглядит следующим образом:

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);
0 голосов
/ 16 октября 2013

сделал бы что-то вроде этого:

 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
  }
0 голосов
/ 25 мая 2011

Похоже, вы также хотите удалить кавычки и добавить % в начало и конец строки поиска.Попробуйте это:

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%
0 голосов
/ 24 мая 2011

Если двойные кавычки каким-либо образом не экранированы, то есть еще одна возможность.Возможно, не так эффективно, как некоторые методы (и, конечно, не так круто, как регулярное выражение Тима), но это может быть разумно понятно, когда следующий парень смотрит на код.Он разбивает строку на двойные кавычки, а затем перебирает значения.Нечетные записи - это части вне кавычек, четные записи - это те, которые находятся внутри кавычек.

  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("%");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...