.NET Regex для "не этой строки" - PullRequest
       15

.NET Regex для "не этой строки"

4 голосов
/ 05 февраля 2010

Я новичок в regex и мне нужно одно выражение:

соответствует «an» и «AN», но не «and» или «AND» и соответствует «o» и «O», но не «или» или «OR» в этом предикате:

й (2or3) И (4OR5) ап (6o7) А.Н. (8O9)

В принципе, я не могу понять, как преобразовать выражение:

var myRegEx = Regex("[0-9 ()]|AND|OR")

в выражении "все, кроме", без учета регистра.

Невозможно использовать функцию границ слов регулярного выражения, поскольку предикат не обязательно должен содержать пробелы.

(Добавлено после того, как два ответа уже были при условии): мне также нужно знать Индекс матча, поэтому я при условии, что мне нужно использовать Метод Regex.Match ().

Спасибо!

Вот что я закончил:

  private bool mValidateCharacters()
  {
     const string legalsPattern = @"[\d ()]|AND|OR";
     const string splitPattern = "(" + legalsPattern + ")";
     int position = 0;
     string[] tokens = Regex.Split(txtTemplate.Text, splitPattern, RegexOptions.IgnoreCase);

     // Array contains every legal operator/symbol found in the entry field
     // and every substring preceeding, surrounded by, or following those operators/symbols
     foreach (string token in tokens)
     {
        if (string.IsNullOrEmpty(token))
        {
           continue;
        }

        // Determine if the token is a legal operator/symbol or a syntax error
        Match match = Regex.Match(token, legalsPattern, RegexOptions.IgnoreCase);

        if (string.IsNullOrEmpty(match.ToString()))
        {
           const string reminder =
              "Please use only the following in the template:" +
              "\n\tRow numbers from the terms table" +
              "\n\tSpaces" +
              "\n\tThese characters: ( )" +
              "\n\tThese words: AND OR";
           UserMsg.Tell("Illegal template entry '" + token + "'at position: " + position + "\n\n" + reminder, UserMsg.EMsgType.Error);
           txtTemplate.Focus();
           txtTemplate.Select(position, token.Length);
           return false;
        }

        position += token.Length;
     }

     return true;
  }

1 Ответ

6 голосов
/ 05 февраля 2010

Рэндал Шварц * Правило : используйте захват в Regex.Match, когда вы знаете, что хотите сохранить, и используйте Regex.Split, когда вы знаете, что хотите выбросить.

Вы написали, что хотите «все, кроме», поэтому

var input = "1and(2or3)AND(4OR5)an(6o7)AN(8O9)";
foreach (var s in Regex.Split(input, @"[\d()]|AND|OR", RegexOptions.IgnoreCase))
  if (s.Length > 0)
    Console.WriteLine("[{0}]", s);

Выход:

[an]
[o]
[AN]
[O]

Чтобы получить смещения, сохраните разделители, заключив в скобки регулярное выражение:

var input = "1and(2or3)AND(4OR5)an(6o7)AN(8O9)";
string pattern = @"([\d()]|AND|OR)";
int offset = 0;
foreach (var s in Regex.Split(input, pattern, RegexOptions.IgnoreCase)) {
  if (s.ToLower() == "an" || s.ToLower() == "o")
    Console.WriteLine("Found [{0}] at offset {1}", s, offset);
  offset += s.Length;
}

Выход:

Found [an] at offset 19
Found [o] at offset 23
Found [AN] at offset 26
Found [O] at offset 30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...