Сведения о вопросе

Fhohir

18:50, 8th August, 2020

Теги

regex   .net-2.0    

Захват повторяющейся группы

Просмотров: 458   Ответов: 9

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

H3Y5NC8E-TGA5B6SB-2NVAQ4E0

и вернуть после использования Сплит: H3Y5NC8E TGA5B6SB 2NVAQ4E0

Я проверяю каждый символ по определенному набору символов (обратите внимание, что буквы 'I', 'O', 'U' & 'W' отсутствуют), поэтому использование string.Split не является опцией. Количество символов в каждой группе может варьироваться, и количество групп также может варьироваться. Я использую следующее выражение:

([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}-?){3}

Это будет соответствовать ровно 3 группам по 8 символов в каждой. Любой более или менее провалит матч. Это работает постольку, поскольку он правильно соответствует входным данным. Однако, когда я использую метод Split для извлечения каждой группы символов, я просто получаю конечную группу. RegexBuddy жалуется, что я повторил саму группу захвата и что я должен поместить группу захвата вокруг повторной группы. Однако ни одна из моих попыток сделать это не привела к желаемому результату. Я уже пробовал такие выражения как это:

(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){4}

Но это не работает.

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


Обратите внимание, что набор символов не включает в себя весь алфавит. Это часть системы активации продукта. Таким образом, все символы, которые могут быть случайно интерпретированы как числа или другие символы, удаляются. например, буквы 'I', 'O', 'U' & 'W' не входят в набор символов.

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



  Сведения об ответе

VCe znayu

18:02, 17th August, 2020

Кстати, вы можете заменить класс символов [ABCDEFGHJKLMNPQRSTVXYZ0123456789] на более читаемый класс вычитаемых символов.

[[A-Z\d]-[IOUW]]

Если вы просто хотите сопоставить 3 группы таким образом, почему бы вам не использовать этот шаблон 3 раза в вашем regex и просто использовать захваченные 1, 2, 3 подгруппы для формирования новой строки?

([[A-Z\d]-[IOUW]]){8}-([[A-Z\d]-[IOUW]]){8}-([[A-Z\d]-[IOUW]]){8}

В 32 году я бы вернулся (не знаю .NET)

return "$1 $2 $3";


  Сведения об ответе

screen

08:10, 3rd August, 2020

Рассмотрев ваш вопрос и приведенные ответы, я пришел к такому выводу:

RegexOptions options = RegexOptions.None;
Regex regex = new Regex(@"([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})", options);
string input = @"H3Y5NC8E-TGA5B6SB-2NVAQ4E0";

MatchCollection matches = regex.Matches(input);
for (int i = 0; i != matches.Count; ++i)
{
    string match = matches[i].Value;
}

Поскольку " - " является необязательным, вам не нужно его включать. Я не уверен, для чего вы использовали {4} в конце? Это позволит найти совпадения на основе того, что вы хотите, а затем с помощью MatchCollection вы можете получить доступ к каждому совпадению, чтобы перестроить строку.


  Сведения об ответе

prince

10:23, 16th August, 2020

Я нашел ответ, который искал. Вот мой рабочий код:

    static void Main(string[] args)
    {
        string pattern = @"^\s*((?<group>[ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){3}\s*$";
        string input = "H3Y5NC8E-TGA5B6SB-2NVAQ4E0";
        Regex re = new Regex(pattern);
        Match m = re.Match(input);

        if (m.Success)
            foreach (Capture c in m.Groups["group"].Captures)
                Console.WriteLine(c.Value);
    }


  Сведения об ответе

$DOLLAR

06:18, 21st August, 2020

Зачем использовать Regex? Если группы всегда разделяются на -, то нельзя ли использовать Split()?


  Сведения об ответе

appple

20:53, 12th August, 2020

Извините, если это не то, что вы предполагали, но ваша строка всегда имеет дефис, разделяющий группы, то вместо использования regex не могли бы вы использовать метод String.Split()?

Dim stringArray As Array = someString.Split("-")


  Сведения об ответе

DINO

07:59, 11th August, 2020

Вы можете использовать этот шаблон:

Regex.Split("H3Y5NC8E-TGA5B6SB-2NVAQ4E0", "([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}+)-?")

Но вам нужно будет отфильтровать пустые строки из результирующего массива. Цитата из MSDN :

Если несколько совпадений соседствуют друг с другом, то в массив вставляется пустая строка.


  Сведения об ответе

padenie

05:51, 10th August, 2020

Каковы определяющие характеристики допустимого блока? Нам нужно было бы знать это, чтобы действительно быть полезными.

Мое общее предложение, проверить кодировку на первом шаге, а затем разделить и проанализировать в отдельном методе, основанном на том, что вы ожидаете. Если это происходит на веб-сайте / в приложении, то вы можете использовать проверку ASP Regex на переднем конце, а затем разбить ее на заднем конце.


  Сведения об ответе

appple

07:41, 19th August, 2020

Если вы просто проверяете значение группы, используйте group (i).значение, то вы получите только последнее. Однако если вы хотите перечислить все случаи захвата этой группы, используйте group(2).захватывает (i).значение, как показано ниже.

system.text.RegularExpressions.Regex.Match("H3Y5NC8E-TGA5B6SB-2NVAQ4E0","(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]+)-?)*").Groups(2).Captures(i).Value


  Сведения об ответе

qwerty101

21:24, 24th August, 2020

Майк,

Вы можете использовать набор символов по вашему выбору внутри группы символов. Все, что вам нужно, это добавить модификатор"+", чтобы захватить все группы. Смотрите мой предыдущий ответ, просто измените [A-Z0-9] на все, что вам нужно (т. е. [ABCDEFGHJKLMNPQRSTVXYZ0123456789])


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться