2016-08-28 3 views
-1

Я разрабатываю приложение C# для извлечения повторяемых паттернов из файла .x12 (txt). Я смог создать регулярное выражение PCRE для выполнения задачи, но не смог адаптировать его к Regex для C#.Пытается адаптировать регулярное выражение PCRE для использования в .NET (C#)

Ниже приводится текст, который я пытаюсь выделить:

HL*1**20*1~ 
PER*IC*XX HEALTH XXXX XXXXX*TE*6822363000*FX*6822364615~ 
NM1*87*2~ 
N3*2448 XXXXX DR~ 
N4*XXXX XXXX*XX*761089998~ 
DMG*D8*19530804*F~ 
NM1*PR*2*XXXXXX MEDICAL MANAGEMENT*****PI*95958~ 
CLM*1111111111*3291.69***13:A:1**A*Y*Y~ 
DTP*434*RD8*20160714-20160714~ 
CL1*3*2*01~ 
HCP*03*480.01~ 
NM1*71*1*XXXXXXX*XXXXXXXX****XX*1111111111~ 
SBR*P*18*UDF******CI~ 
NM1*IL*1*XXXX*XXXXXXX*A***MI*509180801~ 
LX*1~ 
SV2*0250**44.19*UN*1~ 
DTP*472*D8*20160714~ 
SVD*95958*0.00**0250*1~ 
DTP*573*D8*20160726~ 
LX*2~ 
SV2*0311*HC:88172*936.25*UN*1~ 
DTP*472*D8*20160714~ 
SVD*95958*0.00*HC:88172*0311*1~ 
CAS*CO*97*936.25~ 
DTP*573*D8*20160726~ 
LX*3~ 
SV2*0311*HC:88173*477.25*UN*1~ 
DTP*472*D8*20160714~ 
SVD*95958*0.00*HC:88173*0311*1~ 
CAS*CO*97*477.25~ 
DTP*573*D8*20160726~ 
LX*4~ 
SV2*0312*HC:88305*456.5*UN*1~ 
DTP*472*D8*20160714~ 
SVD*95958*0.00*HC:88305*0312*1~ 
CAS*CO*97*456.5~ 
DTP*573*D8*20160726~ 
LX*5~ 
SV2*0360*HC:10022*483.75*UN*1~ 
DTP*472*D8*20160714~ 
SVD*95958*225.41*HC:10022*0360*1~ 
CAS*PR*3*250~ 
DTP*573*D8*20160726~ 
LX*6~ 
SV2*0402*HC:76942*893.75*UN*1~ 
DTP*472*D8*20160714~ 
SVD*95958*0.00*HC:76942*0402*1~ 
CAS*CO*97*893.75~ 
DTP*573*D8*20160726~ 
HL*3**20*1~ <-- FIND UP TO THIS LINE, BUT EXCLUDE FROM RESULTS 

Я знаю, что это длинный блок текста. Таким образом, каждое совпадение регулярных выражений должно содержать две строки, начинающиеся с HL, и перейти к строке, начинающейся с DTP, которая появляется непосредственно перед ather HL, но не включая Next HL.

Тогда регулярное выражение PCRE, которое я использую в блокноте ++, выглядит следующим образом. Я вошел в мое понимание этого и цели послесловия: (.? +) (.? +) (? = ([\ Г \ п] * HL))

^HL DTP ~

  1. старта в начале строки и найдите HL
  2. соберите что-нибудь (включая новые строки и возврат каретки), пока не придете к DTP, за которым следует тильда.
  3. остановка в DTP с чем-либо после нее, которая заканчивается тильдой; AS LONG AS ... что линия DTP встречается перед следующей строкой, начинающейся с HL. Кроме того, исключить следующее HL из матча.

Я не уверен, насколько это сложно, но толчок в правильном направлении был бы ВЗРОСЛЫМ.

+0

Ваше регулярное выражение не находит ни одного в тексте, который вы указали, - https://regex101.com/r/eO7lD2/1 –

+0

Hi Wiktor. Спасибо, что ответили. Это моя проблема. Он работает в блокноте ++. Но .NET не использует регулярные выражения, совместимые с Pearl, такие как notepad ++. Я пытаюсь достичь в .NET того, чего я достиг в блокноте ++. – jjones150

+0

Notepad ++ использует Boost regex, а не PCRE. Ваше регулярное выражение не работает на АЭС, просто проверено. Оба с модификатором DOTALL и без него. Пожалуйста, дважды проверьте, что вы используете, и то, что вы разместили.Несколько советов: 1) В АЭС '^' соответствует началу строки и в .NET, вам нужно использовать флаг Singleline (или добавить '(? M)' в начало шаблона), 2) Параметр * '.' соответствует параметру newline * в NPP равен передаче флага' RegexOptions.Singleline' методу 'Regex.Match' или использованию версии модификатора' (? s) 'inline в начале регулярного выражения , –

ответ

0

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

^HL [\ ш \ с * ~: -., @() \ Г \ п]? DTP [\ ш *] ~

Еще раз спасибо

1

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

ПО Regex: (.? +) (.? +)^HL DTP ~ (? = ([\ г \ п] * HL))

^HL    # strat with HL 
.+?     # any character ,one or more, as few as possible 
(
(?<dtp>DTP.+?~) # named group start with DTP 
           # any character ,one or more, as few as possible 
          # ~ 
(.+?) 
(?=DTP) # match DTP but exclude it from capture 
)+ 

Я проверил его по адресу: http://regexstorm.net/tester

Захваченные группы являются:

DTP*434*RD8*20160714-20160714~ 
    DTP*472*D8*20160714~ 
    DTP*573*D8*20160726~ 
    DTP*472*D8*20160714~ 
    DTP*573*D8*20160726~ 
    DTP*472*D8*20160714~ 
    DTP*573*D8*20160726~ 
    DTP*472*D8*20160714~ 
    DTP*573*D8*20160726~ 
    DTP*472*D8*20160714~ 
    DTP*573*D8*20160726~ 
    DTP*472*D8*20160714~ 

Попробуйте на: http://regexstorm.net/tester

опции: игнорировать пробелы/SingleLine/многострочного

+0

Я сомневаюсь в ленивом Точка соответствия шаблон будет работать здесь. Если блок с квалификационным DTP находится во втором блоке, первый и второй блоки будут совпадать. –

+0

@Wiktor, чтобы остановить совпадение ленивой точки (. +?) В DTP, мне нужно захватить DTP во втором блоке, но исключить его с помощью Patten (? = DTP). Если я удалил второй блок (? = DTP), regex поймает только один DTP. Я тестировал шаблон по адресу http://regexstorm.net/tester с результатом, указанным в моем ответе. –