Regex .net Получение только последнего совпадения из списка позиций - PullRequest
0 голосов
/ 12 декабря 2018

Я не часто использую Regex.Я пытаюсь получить номера деталей из строки.Я провел целый день.

Я ожидаю 2 матча за "Строку"

 __40X0343 1.00
 __C734X77G 2.00

, и в этих матчах я ожидаю эти матчи

PartNo 40X0343 OrderQuantity 1.00 for Line 1
PartNo C734X77G OrderQuantity 2.00 for Line 2

, но ятолько получить последний матч не оба.Любая помощь будет отличной

регулярное выражение:

(?x)Required\sDate
(?<Line>__
(?<PartNo>[a-zA-Z0-9-]*)\S
(?<OrderQuantity>[0-9.]+)
)*

string

__Required Date__40X0343 1.00__C734X77G 2.00__Net Order:__Sales Tax:__Freight:__Order Total:__0.00 __0.00 __5,328.50 __5,328.50 __or by fax  

результаты из инструмента регулярных выражений

Full match 2-44 `Required Date__40X0343 1.00__C734X77G 2.00` 
Group `Line` 29-44 `__C734X77G 2.00` 
Group `PartNo` 31-39 `C734X77G` 
Group `OrderQuantity` 40-44 `2.00` 

Отредактировано для лучшей иллюстрациимоя проблема

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Эта часть вашего регулярного выражения (?<PartNo>[a-zA-Z0-9-]*)\S захватывает группу с именем PartNo и соответствует [a-zA-Z0-9-]*, за которым следует \S, что соответствует не пробелу, но в соответствии с данными вашего примера, которое должно быть \s, которое соответствуетсимвол пробела

Вы получаете только последний матч, потому что вы повторяете группу захвата .

Если вы ожидаете 2 матча, вы можете захватить OrderQuantity в той же группекак PartNo.

Используя C #, вы можете использовать Group.Captures и использовать имя группы PartNo.Затем вы можете получить снимки и зациклить их.

Например:

string pattern = @"(?x)Required\sDate
(?<Line>__
(?<PartNo>[a-zA-Z0-9-]*\s[0-9.]+)
)*";
string str = @"__Required Date__40X0343 1.00__C734X77G 2.00__Net Order:__Sales Tax:__Freight:__Order Total:__0.00 __0.00 __5,328.50 __5,328.50 __or by fax";        
Regex regex = new Regex(pattern);
MatchCollection matchColl = regex.Matches(str);
if (matchColl != null) 
    foreach (Match match in matchColl) 
        foreach (Capture c in match.Groups["PartNo"].Captures) 
            Console.WriteLine(c.Value);

Результат

40X0343 1.00
C734X77G 2.00

См. Демонстрацию C #

Другой вариант - иметь несколько именованных групп захвата с PartNo и OrderQuantity regex demo или без OrderQuantity group regex demo

0 голосов
/ 13 декабря 2018

В качестве первых шагов похоже, что вы пропускаете синтаксис повторения, и, как побочный продукт, усложняете получение групп впоследствии.Другими словами, эта часть:

    (?<PartNo>[a-zA-Z0-9-]*)__

должна выглядеть примерно так:

    ((?<PartNo>[a-zA-Z0-9-]*)__)+

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

Если выВы уверены, что всегда будет номер детали, я бы опустил ? во внутренней группе захвата, технически это противоречит +, и хотя это не имеет значения, когда я его пробовал (в Notepad ++),нет смысла путать проблему.

Похоже, вам нужно будет провести тщательную оценку идентификаторов групп захвата после захвата, хотя я не использую псевдонимы, такие как <PartNo>, и поэтому я могу 'не могу сказать наверняка, может быть, это не так сложно.

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