RegEx匹配没有单个字母分隔符

时间:2008-12-16 17:21:09

标签: c# regex lookahead negative-lookahead

Medicare Eligibility EDI Example Responses正是我想要匹配的。

我有一个看起来像这样的字符串:

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循环编程它,如果我无法解决问题就找到冒号索引。

我尝试过使用negative lookahead但我没有到达任何地方。这是C#,我正在测试时使用this tester(。Net)以及The Regex Coach(非.Net)。

我尝试过使用它:

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

但这只匹配键和它们的冒号,如“LN:”,“FN:”等。

如果我使用:

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

它也会消耗下一个匹配的两个字符键和冒号,导致我只匹配所有其他键/值对。

有没有办法让我在.Net中使用RegEx正确匹配这些,或者我是否坚持使用更程序化的解决方案?请记住,我不能认为键总是大写字母。它们可能包含数字,但它们总是两个字符,然后是冒号。

提前感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:8)

我认为你想要的是积极的前瞻,而不是消极的,所以你在当前位置之前找到了关键冒号组合,但你没有消耗它。这似乎适用于您的测试示例:

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

产量:

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

注意:我在测试输出中添加了冒号,它们不会被正则表达式捕获。

编辑:谢谢,道格拉斯,我编辑了正则表达式以捕获字符串结尾,因此也捕获了最后一个条目。

答案 1 :(得分:0)

这适用于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]

答案 2 :(得分:0)

查看链接每个字段的长度是固定的,因此您可以执行以下操作:

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;
}