Соответствие RegEx без единого разделителя букв - PullRequest
2 голосов
/ 16 декабря 2008

Пример ответов на вопросы EDI по программе Medicare - это то, что я пытаюсь сопоставить.

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

LN:SMITHbbbbbbbbFN:SAMANTHAbbBD:19400515PD:1BN:123456PN:9876543210GP:ABCDEFGHIJKLMNOID:123456789012345bbbbbPC:123PH:8005551212CD:123456PB:123ED:20060101TD:2070101LC:NFI:12345678FE:20070101FT:20080101

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

Key | Value
-------------------
LN  | SMITHbbbbbbbb
FN  | SAMANTHAbb
BD  | 19400515
... etc

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

Я пытался использовать отрицательный взгляд , и я никуда не доберусь. Это C #, и я использую этот тестер (.Net) во время тестирования вместе с Regex Coach (не .Net).

Я пытался использовать это:

([\w]{2})\:(?![\w]{2}\:)

Но это соответствует только ключам и их двоеточиям, таким как "LN:", "FN:" и т. Д.

Если я использую:

([\w]{2})\:(.+?)([\w]{2})\:

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

Есть ли способ для меня, чтобы сопоставить их, используя RegEx в .Net правильно, или я застрял с более процедурным решением? Имейте в виду, я не могу предположить, что ключи всегда будут заглавными буквами. Они могут содержать числа, но они всегда будут двумя символами, а затем двоеточием.

Заранее спасибо за любую помощь, которую я могу получить.

Ответы [ 3 ]

8 голосов
/ 16 декабря 2008

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

([\w]{2})\:(.+?)(?=[\w]{2}\:|$)

Уступая:

LN: SMITHbbbbbbbb
FN: SAMANTHAbb
BD: 19400515
PD: 1
BN: 123456
PN: 9876543210
...

Примечание. Я добавил двоеточия в свой тестовый вывод, они не захвачены регулярным выражением.

РЕДАКТИРОВАТЬ: Спасибо, Дуглас, я отредактировал регулярное выражение для захвата конца строки, чтобы захватить и последнюю запись.

0 голосов
/ 17 декабря 2008

Глядя на ссылку, каждое поле имеет фиксированную длину, поэтому вы можете сделать что-то вроде этого:

int pos = 0;
Dictionary<string, string> parsedResults = new Dictionary<string, string>();

foreach (int length in new int[] { 13, 10, 8, 1, 6, 10, 15, 20, 3, 10, 6, 3, 8, 8, 1, 8, 8, 8, })
{
    string fieldId = message.Substring(pos, 2);
    string fieldValue = message.Substring(pos + 3, length);
    parsedResults.Add(fieldId, fieldValue);
    pos += length + 3;
}
0 голосов
/ 16 декабря 2008

Это работает в JavaScript (я всегда запускаю консоль ошибок в Firefox, чтобы поиграть с регулярными выражениями), но она также должна нормально работать в .NET:

([^:]{2}):((?:[^:](?!(?:[^:]:)))+)

Использует негативный взгляд:

( -> start capturing first token (the label)
    [^:]{2} -> two non-colon characters
) -> end capturing first token
: -> skip the colon
( -> start capturing the second token (the value)
    (?: -> don't capture this group as a token
        [^:](?! -> a non-colon character, not followed by:
                (?: -> don't capture this group
                    [^:]: -> a non-colon, followed by a colon
                ) -> end group
            ) -> end negative lookahead
    )+ -> one or more of this group
) -> end capturing the second token

Тест:

"LN:SMITHbbbbbbbbFN:SAMANTHAbbBD:19400515"
    .replace(
        /([^:]{2}):((?:[^:](?!(?:[^:]:)))+)/g,
        "[$1] = [$2]\n")

Урожайность:

[LN] = [SMITHbbbbbbbb]
[FN] = [SAMANTHAbb]
[BD] = [19400515]
...