совпадение нескольких строк регулярного выражения после строки - PullRequest
1 голос
/ 11 июля 2020

Я пытаюсь извлечь раздел PROCEDURE из CLAIM, EOB и COB из текстового файла.

и создать такой объект, как

claim : [{PROCEDURE1}, {PROCEDURE2}, {PROCEDURE3}],
eob : [{PROCEDURE1}, {PROCEDURE2}, {PROCEDURE3}],
cob: [{PROCEDURE1}, {PROCEDURE2}, {PROCEDURE3}]

let data = `    SEND CLAIM {
       PREFIX="9403        "
       PROCEDURE { /* #1  */
          PROCEDURE_LINE="1"
          PROCEDURE_CODE="01201"
        
       }
       PROCEDURE { /* #2  */
          PROCEDURE_LINE="2"
          PROCEDURE_CODE="02102"
         
       }
       PROCEDURE { /* #3  */
          PROCEDURE_LINE="3"
          PROCEDURE_CODE="21222"
       
       }
    }
    
    SEND EOB {
          PREFIX="9403        "
          OFFICE_SEQUENCE="000721"
          PROCEDURE { /* #1 */
             PROCEDURE_LINE="1"
             ELIGIBLE="002750"
          }
          PROCEDURE { /* #2 */
             PROCEDURE_LINE="2"
             ELIGIBLE="008725"
          }
          PROCEDURE { /* #3 */
             PROCEDURE_LINE="3"
             ELIGIBLE="010200"
          }
    }
    
    SEND COB {
       PREFIX="TEST4       "
       OFFICE_SEQUENCE="000721"
       PROCEDURE { /* #1  */
          PROCEDURE_LINE="1"
          PROCEDURE_CODE="01201"
        
       }
       PROCEDURE { /* #2  */
          PROCEDURE_LINE="2"
          PROCEDURE_CODE="02102"
       }
       PROCEDURE { /* #3  */
          PROCEDURE_LINE="3"
          PROCEDURE_CODE="21222"
          DATE="19990104"
       }
       PRIME_EOB=SEND EOB {
          PREFIX="9403        "
          OFFICE_SEQUENCE="000721"
          PROCEDURE { /* #1 */
             PROCEDURE_LINE="1"
             ELIGIBLE="002750"
          }
          PROCEDURE { /* #2 */
             PROCEDURE_LINE="2"
             ELIGIBLE="008725"
          }
          PROCEDURE { /* #3 */
             PROCEDURE_LINE="3"
             ELIGIBLE="010200"
          }
    
       }
    }`
    
    let re = /(^\s+PROCEDURE\s\{)([\S\s]*?)(?:})/gm
    
    console.log(data.match(re));

Вот что я пробовал до сих пор (^\s+PROCEDURE\s\{)([\S\s]*?)(?:}), но я не могу понять, как я могу сопоставить PROCEDURE s после ключа CLAIM или EOB

Ответы [ 3 ]

1 голос
/ 11 июля 2020

Для «претензии» вы можете сопоставить следующее регулярное выражение.

/(?<=^ *SEND CLAIM +\{\r?\n(?:^(?! *SEND EOB *\{)(?! *SEND COB *\{).*\r?\n)*^ *PROCEDURE *)\{[^\}]*\}/

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

Это соответствует следующим строкам, которые, как я полагаю, могут быть легко сохранить в массив с добавлением кода Javascript.

         { /* CLAIM #1  */  
   PROCEDURE_LINE="1"
   PROCEDURE_CODE="01201"
    
}

          { /* CLAIM #2  */
   PROCEDURE_LINE="2"
   PROCEDURE_CODE="02102"
  
}

          { /* CLAIM #3  */
   PROCEDURE_LINE="3"
   PROCEDURE_CODE="21222"
   
}

Javascript Механизм регулярных выражений выполняет следующие операции.

(?<=                 : begin positive lookbehind
  ^                  : match beginning of line
  \ *SEND CLAIM\ +   : match 'SEND CLAIM' surrounded by 0+ spaces
  \{\r?\n            : match '{' then line terminators
  (?:                : begin non-capture group
    ^                : match beginning of line
    (?!              : begin negative lookahead
      \ *SEND EOB\ * : match 'SEND EOB' surrounded by 0+ spaces
      \{             : match '{'
    )                : end negative lookahead
    (?!              : begin negative lookahead
      \ *SEND COB\ * : match 'SEND COB' surrounded by 0+ spaces
      \{             : match '{'
    )                : end negative lookahead
    .*\r?\n          : match line including terminators
  )                  : end non-capture group
  *                  : execute non-capture group 0+ times
  ^                  : match beginning of line
  \ *PROCEDURE\ *    : match 'PROCEDURE' surrounded by 0+ spaces 
)                    : end positive lookbehind
\{[^\}]*\}           : match '{', 0+ characters other than '}', '}' 

Я отказался от пробелов выше, чтобы улучшить читаемость.

Для «eob» используйте слегка измененное регулярное выражение:

/(?<=^ *SEND EOB +\{\r?\n(?:^(?! *SEND CLAIM *\{)(?! *SEND COB *\{).*\r?\n)*^ *PROCEDURE *)\{[^\}]*\}/

EOB regex

Я не предпринимал попыток сделать то же самое для «cob», поскольку эта часть имеет другую структуру, чем «заявка» и «eob», и мне это непонятно как с этим обращаться.

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

0 голосов
/ 13 июля 2020

То, что вы пытаетесь сделать, - это написать синтаксический анализатор для синтаксиса, используемого в вашем текстовом файле.
Если посмотреть на синтаксис, он выглядит примерно как JSON.
Я бы рекомендовал изменить синтаксис с регулярными выражениями, чтобы получить действительный синтаксис JSON и проанализировать его с помощью парсера JavaScript JSON. Парсер может обрабатывать рекурсию. В конце у вас будет объект JavaScript, который позволяет вам удалять или добавлять все, что вам нужно. Кроме того, иерархия источника будет сохранена.

Этот код выполняет работу для предоставленного примера:

let data = `    SEND CLAIM {
// your text file contents
}`;

// handle PRIME_EOB=SEND EOB {
var regex = /(\w+)=\w+.*{/gm;
var replace = data.replace(regex, "$1 {");

// append double quotes in lines like PROCEDURE_LINE="1"
var regex = /(\w+)=/g;
var replace = replace.replace(regex, "\"$1\": ");

// append double quotes in lines like PROCEDURE {
var regex = /(\w+.*)\s{/g;
var replace = replace.replace(regex, "\"$1\": {");

// remove comments: /* */
var regex = /\/\**.*\*\//g;
var replace = replace.replace(regex, "");

// append commas to lines i.e. "PROCEDURE_LINE": "2"
var regex = /(\".*\":\s*\".*\")/gm;
var replace = replace.replace(regex, "$1,");

// append commas to '}'
var regex = /^.*}.*$/gm;
var replace = replace.replace(regex, "},");

// remove trailing commas
var regex = /\,(?!\s*?[\{\[\"\'\w])/g;
var replace = replace.replace(regex, "");

// surround with {}
replace = "{" + replace + "}";

console.log(replace);
var obj = JSON.parse(replace);
console.log(obj);

JSON выглядит следующим образом:

{    "SEND CLAIM": {
       "PREFIX": "9403        ",
       "PROCEDURE": { 
          "PROCEDURE_LINE": "1",
          "PROCEDURE_CODE": "01201"
        
},
       "PROCEDURE": { 
          "PROCEDURE_LINE": "2",
          "PROCEDURE_CODE": "02102"

И последний объект появляется в отладчике вот так введите описание изображения здесь .

Мне не совсем понятно, как должен выглядеть ваш окончательный массив или объект. Но отсюда я рассчитываю лишь на небольшие усилия, чтобы произвести то, что вы желаете.

0 голосов
/ 11 июля 2020

Всегда ли CLAIM, EOB и COB будут в одном и том же порядке? Если это так, вы можете разделить текст перед использованием регулярного выражения, которое у вас уже есть:

const procRegex = /(^\s+PROCEDURE\s\{)([\S\s]*?)(?:})/gm;

let claimData = data.split("EOB")[0];
let claimProcedures = claimData.match(procRegex);

let eobData = data.split("COB")[0].split("EOB")[1];
let eobProcedures = eobData.match(procRegex);

let cobData = data.split("COB")[1];
let cobProcedures = cobData.match(procRegex);

// If you want to leave out the PRIME_EOB, you can split COB again
cobData = cobData.split("EOB")[0];
cobProcedures = cobData.match(procRegex);

console.log(claimProcedures);

Вывод:

[
  '       PROCEDURE { /* #1  */\n' +
    '          PROCEDURE_LINE="1"\n' +
    '          PROCEDURE_CODE="01201"\n' +
    '        \n' +
    '       }',
  '       PROCEDURE { /* #2  */\n' +
    '          PROCEDURE_LINE="2"\n' +
    '          PROCEDURE_CODE="02102"\n' +
    '         \n' +
    '       }',
  '       PROCEDURE { /* #3  */\n' +
    '          PROCEDURE_LINE="3"\n' +
    '          PROCEDURE_CODE="21222"\n' +
    '       \n' +
    '       }'
]

Demo

As альтернативный метод, ваши данные не так уж далеки от действительного JSON, так что вы можете работать с этим. Приведенный ниже код переводит данные в JSON, а затем анализирует их в Javascript объект, который вы можете использовать, как хотите.

/* data cannot have Javascript comments in it for this to work, or you need
   another regex to remove them */

data = data.replace(/=/g, ":") // replace = with :
  .replace(/\s?{/g, ": {") // replace { with : {
  .replace(/SEND/g, "") // remove "SEND"
  .replace(/\"\s*$(?!\s*\})/gm, "\",") // add commas after object properties
  .replace(/}(?=\s*\w)/g, "},") // add commas after objects
  .replace(/(?<!\}),\s*PROCEDURE: /g, ",\nPROCEDURES: [") // start procedures list
  .replace(/(PROCEDURE:[\S\s]*?\})\s*(?!,\s*PROCEDURE)/g, "$1]\n") // end list
  .replace(/PROCEDURE: /g, "") // remove "PROCEDURE"
  .replace("PRIME_EOB: EOB:", "PRIME_EOB:") // replace double key with single key. Is this the behavior you want?
  .replace(/(\S*):/g, "\"$1\":") // put quotes around object key names

let dataObj = JSON.parse("{" + data + "}");

console.log(dataObj.CLAIM.PROCEDURES);

Вывод:

[ { PROCEDURE_LINE: '1', PROCEDURE_CODE: '01201' },
  { PROCEDURE_LINE: '2', PROCEDURE_CODE: '02102' },
  { PROCEDURE_LINE: '3', PROCEDURE_CODE: '21222' } ]

Демо

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