Шаблон регулярных выражений Powershell для EDI

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

То, что мне нужно, скорее всего, основное, но мне нужна помощь. Мне нужно найти все экземпляры сегмента и извлечь из него определенное значение элемента. Искомый текст будет прочитан как одна длинная строка без CR/LF/и т.д.

Пример данных:

~SV1*HC:V2020*35*UN*1***1~DTP*472*D8*20120807~REF*6R*
~SV1*HC:V2100:LT*28.98*UN*1***1~DTP*472*D8*20120807~REF*6R*
~SV1*HC:92014*165*UN*1***1~DTP*472*D8*20120716~REF*6R*

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

Select-String -pattern '~svd\*\w+\*(\d+|\d+\.\d+)\*' -input $string -AllMatches | %{$_.Matches} | %{$_.Groups[1]} | %{$_.Value}

В идеале я хотел бы найти экземпляр «~ SV1 *», перейти к следующей звездочке, а затем прочитать все через следующую звездочку. Таким образом, не имеет значения, какая там буква/цифра/символ, он ее пропускает. В приведенном выше примере данных я хотел бы вернуть 35, 28,98, 165. Если нет, то я могу работать с тем, что у меня есть, но сопоставление комбинаций слов/несловных символов меня бросает, так как я не знаю, в каком порядке они могут существовать. Все остальное, с чем я играл, продолжало тянуть остальную часть струны и не останавливалось должным образом.

Если я смогу заставить его сделать это, я был бы очень счастлив:

~SV1*<skip this>*<get this>*<skip to next SV1>~SV1*<skip this>*<get this>*<skip to next SV1>

Наконец, извлекаемые данные представляют собой денежное поле, поэтому оно может иметь или не иметь десятичное число. Если есть более чистый способ, чем (\d+|\d+.\d+), я только за.

Спасибо


person David Jones    schedule 02.11.2012    source источник


Ответы (2)


Используйте такой шаблон:

 ~sv\d\*[^*]*\*([^*]*)\*
person SpacedMonkey    schedule 02.11.2012
comment
Это на самом деле работало лучше для моей ситуации, так как я мог подключить сегмент и получить нужные результаты, настроив звездочки для элементов, которые я хотел пропустить. Спасибо! - person David Jones; 03.11.2012

Отправная точка, но вам нужно ее протестировать:

Select-String -pattern '(?<=~sv\d\*.*\*)(\d*\.?\d+)(?=\*un)' -input $string -AllMatches | %{$_.Matches} | % {$_.Groups[1]} | %{$_.Value}

Использование данных вашего примера возвращает 35, 28,98, 165.

person CB.    schedule 02.11.2012
comment
Первоначальные тесты выглядят хорошо. Я отвечу позже сегодня или в понедельник, как только я проверю это. Вычисление суммы по всем этим значениям теперь дает ожидаемый результат, до того, как я пропустил совпадения и получил меньшие числа. Если вы не возражаете, не могли бы вы дать мне краткий обзор того, почему именно это работает? Особенно (?=*un). Спасибо! - person David Jones; 02.11.2012
comment
@DavidJones (?‹=...) и (?=...) являются утверждениями просмотра назад и вперед. Здесь regular-expressions.info/lookaround.html вы можете найти хорошее объяснение - person CB.; 02.11.2012
comment
Хороший ресурс, много полезной информации. Ваш пример также помог мне найти некоторые другие вещи, которые я сделал неправильно, еще раз спасибо! - person David Jones; 03.11.2012