简体   繁体   中英

Match string with hex string

I'm converting some of my code from C++, and wanted to take advantage of Regex for a scenario in my program. The user story says that the string needs to be 3 sets of hex numbers between 4 tags (however these tags didn't have end tags sigh ) The 4 tags to be used were <DIV> , <GKY> , <UID> , <END> well I like to give my users a little more flexibility in their code if they so desire, so what I was hoping for a simple regex expression that I could write a simple method around. I found the code I wanted to match if it is a hex string ( think I do atleast), but i can't get my Reg expression test tool to match with a tag behind it. Take this string for example.

<DIV>A9F81123C8288B34758D0481E8271843<GKY><UID><END>

I wouldn't mind if the regex expression returned <DIV>A9... or if it return just the hex string. but I would want it to be able to return it from all 3 of these scenarios

  • <DIV>A9F81123C8288B34758D0481E8271843<GKY><UID><END>
  • <GKY><DIV>A9F81123C8288B34758D0481E8271843<UID><END>
  • <GKY><UID><DIV>A9F81123C8288B34758D0481E8271843<END>

a full key example would look something like this

<DIV>A9F81123C8288B34758D0481E8271843<GKY>1234568790ABCDEF0<UID>0422ABCDEF<END>

so far all I have in my unit test is to tell that the string contains the 4 Tags. So i'm stuck right here

    public static KeyInputParser ParseKeyInputString(string inputKey)
    {
        if (string.IsNullOrEmpty(inputKey)) throw new ArgumentNullException("inputKey", "Input Key can't be null or empty");
        inputKey = inputKey.ToUpper();
        var key = new KeyInputParser();
        AssertKeyContainsTheseTags(inputKey, "<DIV>", "<GKY>", "<UID>", "<END>");

        //DIV must always be 16 bytes
        string div = Regex.Match(inputKey, @"<DIV>^([A-Fa-f0-9]{2}){16}$").Value;
        //UID can be 5, 7, or 10 bytes
        //not sure on GKY but it must be more than 1 byte
        return key;
    }

div is returning empty

If you do not really care about tags themselves, you can try this:

(?<=>)[A-Fa-f0-9]+(?=<)

It correctly matches all your test cases, see it in action on Rubular .

If you want the preceding tag as well, this is ok (preview here ):

(?<tag><\w+>)(?<string>[A-Fa-f0-9]+)(?=<)
string div = Regex.Match(inputKey, @"<DIV>([A-Fa-f0-9]{32})").Value;

It should work for you:

^((?<gdiv><DIV>[A-Fa-f0-9]*)|(?<ggky><GKY>[A-Fa-f0-9]*)|(?<guid><UID>[A-Fa-f0-9]*))*<END>$

Tests:

input:   <DIV>A9F81123C8288B34758D0481E8271843<GKY><UID><END>
matches: gdiv   <DIV>A9F81123C8288B34758D0481E8271843
         ggky   <GKY>
         guid   <UID>

input:   <GKY><DIV>A9F81123C8288B34758D0481E8271843<UID><END>
matches: gdiv   <DIV>A9F81123C8288B34758D0481E8271843
         ggky   <GKY>
         guid   <UID>

input:   <GKY><UID><DIV>A9F81123C8288B34758D0481E8271843<END>
matches: gdiv   <DIV>A9F81123C8288B34758D0481E8271843
         ggky   <GKY>
         guid   <UID>

input:   <UID>0422ABCDEF<DIV>A9F81123C8288B34758D0481E8271843<GKY>1234568790ABCDEF0<END>
matches: gdiv   <DIV>A9F81123C8288B34758D0481E8271843
         ggky   <GKY>1234568790ABCDEF0
         guid   <UID>0422ABCDEF

input:   <GKY>1234568790ABCDEF0<DIV>A9F81123C8288B34758D0481E8271843<UID>0422ABCDEF<END>
matches: gdiv   <DIV>A9F81123C8288B34758D0481E8271843
         ggky   <GKY>1234568790ABCDEF0
         guid   <UID>0422ABCDEF

See examples at rebular .

NOTE:

While one of tags ( DIV , GKY , or UID ) values may be empty, so I would recommend you to use [A-Fa-f0-9]* instead of -for example- [A-Fa-f0-9]{16} and test length of values by your self.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM