RegEx для разбора повторных групп - PullRequest
2 голосов
/ 02 июня 2019

Исходная строка содержит теги вроде этого:

>>>tagA
contents 1
<<<tagA
...
>>>tagB
contents 2
<<<tagB
...

Мне нужно извлечь имена тегов и содержимое внутри них. Вот что у меня есть, но все еще не работает:

(?<=(>>>(?<tagName>.+)$))(?<contents2>.*?)(?=(<<<.+)$)

Это приводит к двум совпадениям, но tagName во втором совпадении захватывает несколько строк:

tagA 
contents 1 
<<<tagA

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 02 июня 2019

Вы можете использовать

>>>(?<tagName>.+?)[\r\n]+(?s:(?<contents>.*?))<<<

См. Демоверсию regex

Детали

  • >>> - подстрока >>>
  • (?<tagName>.+?) - Группа "tagName": любые 1+ символов, как можно меньше
  • [\r\n]+ - один или несколько символов CR или LF
  • (?s:(?<contents>.*?)) - Группа «содержимое»: встроенная группа модификаторов, соответствующая любым 0+ символам, но как можно меньше
  • <<< - подстрока <<<.

В C #:

var matches = Regex.Matches(s, @">>>(?<tagName>.+?)[\r\n]+(?s:(?<contents>.*?))<<<");

См. Демоверсию C # :

var s = ">>>tagA\ncontents 1\n<<<tagA\n...\n>>>tagB\ncontents 2\n<<<tagB\n...";
var matches = Regex.Matches(s, @">>>(?<tagName>.+?)[\r\n]+(?s:(?<contents>.*?))<<<");
foreach (Match m in matches) {
    Console.WriteLine(m.Groups["tagName"].Value);
    Console.WriteLine(m.Groups["contents"].Value);
}

Выход:

tagA
contents 1

tagB
contents 2
1 голос
/ 02 июня 2019

Здесь мы, скорее всего, начнем с простого выражения, которое ограничено >>> и <<<, может быть, что-то похожее на:

>>>(.+)\s*(.+)\s*<<<.+

, которое мы получаем желаемыми данными в этих двух снимкахgroups:

(.+)

, и мы запишем остальную часть нашей проблемы.

Демонстрация

Тест

using System;
using System.Text.RegularExpressions;

public class Example
{
    public static void Main()
    {
        string pattern = @">>>(.+)\s*(.+)\s*<<<.+";
        string input = @">>>tagA
            contents 1
            <<<tagA

            >>>tagB
            contents 2
            <<<tagB

            >>>tagC

            contents 2

<<<tagC
";
        RegexOptions options = RegexOptions.Multiline;

        foreach (Match m in Regex.Matches(input, pattern, options))
        {
            Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
        }
    }
}

Схема RegEx

jex.im визуализирует регулярные выражения:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...