Ключ соответствия регулярному выражению = шаблон "значение" - PullRequest
2 голосов
/ 23 июня 2010

Я хочу сопоставить следующий шаблон:

key="value" key="value" key="value" key="value" ...

, где ключ и значение [a-z0-9] +, оба должны быть сгруппированы (2 группы, символы "-" могут быть сопоставлены или пропущены)

ввод, который не должен совпадать:
ключ = "значение" ключ = "значение" (без пробелов между парами)

Пока я получил это (не синтаксис .NET):

([a-z0-9]+)=(\"[a-z0-9]+\")(?=\s|$)

проблема в том, что он соответствует key4 = "value4" на входе:

 key3="value3"key4="value4"

Ответы [ 4 ]

2 голосов
/ 23 июня 2010

Я думаю, что предложение SilentGhost касается использования String.Split ()

Примерно так:

String keyValues = "...";

foreach(String keyValuePair in keyValues.Split(' '))
    Console.WriteLine(keyValuePair);

Это гораздо быстрее и проще.

2 голосов
/ 23 июня 2010

Спецификация не очень понятна, но вы можете попробовать:

(?<!\S)([a-z0-9]+)=("[a-z0-9]+")(?!\S)

Или, как строковый литерал C #:

"(?<!\\S)([a-z0-9]+)=(\"[a-z0-9]+\")(?!\\S)"

При этом используются отрицательные обходные пути, чтобы гарантировать, чтопара ключ-значение не предшествует и не сопровождается непробельными символами.

Вот пример фрагмента (, как видно на ideone.com ):

   var input = "key1=\"value1\" key2=\"value2\"key3=\"value3\" key4=\"value4\"";
   Console.WriteLine(input);
   // key1="value1" key2="value2"key3="value3" key4="value4"

   Regex r = new Regex("(?<!\\S)([a-z0-9]+)=(\"[a-z0-9]+\")(?!\\S)");
   foreach (Match m in r.Matches(input)) {
     Console.WriteLine(m);
   }
   // key1="value1"
   // key4="value4"

Похожие вопросы


При проверке всего ввода

Вы можете использовать Regex.IsMatch, чтобы увидеть, соответствует ли строка ввода тому, что должно быть правильным шаблоном ввода.Вы также можете использовать тот же шаблон для извлечения ключей / значений, благодаря тому, что .NET regex позволяет вам получать доступ к отдельным захватам.

   string[] inputs = {
      "k1=\"v1\" k2=\"v2\" k3=\"v3\" k4=\"v4\"",
      "k1=\"v1\" k2=\"v2\"k3=\"v3\" k4=\"v4\"",
      "    k1=\"v1\"      k2=\"v2\"     k3=\"v3\"     k4=\"v4\"     ",
      "     ",
      " what is this? "
   };

   Regex r = new Regex("^\\s*(?:([a-z0-9]+)=\"([a-z0-9]+)\"(?:\\s+|$))+$");
   foreach (string input in inputs) {
     Console.Write(input);
     if (r.IsMatch(input)) {
        Console.WriteLine(": MATCH!");
        Match m = r.Match(input);
        CaptureCollection keys   = m.Groups[1].Captures;
        CaptureCollection values = m.Groups[2].Captures;
        int N = keys.Count;
        for (int i = 0; i < N; i++) {
           Console.WriteLine(i + "[" + keys[i] + "]=>[" + values[i] + "]");
        }
     } else {
        Console.WriteLine(": NO MATCH!");
     }
   }

Приведенные выше отпечатки (, как видно на ideone.com):

k1="v1" k2="v2" k3="v3" k4="v4": MATCH!
0[k1]=>[v1]
1[k2]=>[v2]
2[k3]=>[v3]
3[k4]=>[v4]
k1="v1" k2="v2"k3="v3" k4="v4": NO MATCH!
    k1="v1"      k2="v2"     k3="v3"     k4="v4"     : MATCH!
0[k1]=>[v1]
1[k2]=>[v2]
2[k3]=>[v3]
3[k4]=>[v4]
     : NO MATCH!
 what is this? : NO MATCH!

Ссылки


Объяснение шаблона

Шаблон для проверки всего ввода по существу:

maybe leading
spaces       ___ end of string anchor
  |         /
^\s*(entry)+$
|          \
beginning   \__ one or more entry
of string
anchor

Где каждая запись:

key=value(\s+|$)

То есть пара ключ / значение, за которой следуют либо пробелы, либо конец строки.

1 голос
/ 23 июня 2010

I секунда ответ Йенса (но я все еще слишком мал, чтобы комментировать ответы других).

Кроме того, я нашел эту ссылку на регулярные выражения сайт, чтобы быть довольно удивительным.На странице Advanced есть раздел, посвященный Lookaround, и еще несколько заметок о Lookbehind .

.
1 голос
/ 23 июня 2010

Используйте взгляд назад, как вы использовали свой взгляд:

(?<=\s|^)([a-z0-9]+)=(\"[a-z0-9]+\")(?=\s|$) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...