Regex Get result if found and if not get another result

Viewed 90

I'm trying to get the max resolution from m3u8 file.

Here's the sample m3u8 content:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=149000,RESOLUTION=320x180,CODECS="avc1.77.30, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_0_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=298000,RESOLUTION=320x180,CODECS="avc1.77.30, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_1_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=499000,RESOLUTION=640x360,CODECS="avc1.64001f, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_2_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=640x360,CODECS="avc1.64001f, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_3_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1062000,RESOLUTION=960x540,CODECS="avc1.77.30, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_4_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1361000,RESOLUTION=960x540,CODECS="avc1.77.30, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_5_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1503000,RESOLUTION=1280x720,CODECS="avc1.64001f, mp4a.40.2",CLOSED-CAPTIONS=NONE
https://URL/index_6_av.m3u8?null=0&id=AgBuNs5OuBzaVwrmOF+jXvWJ+HkjL%2fShsITuRsvq00%2f+IYwrOKyjWNrak9RN+Vq0bDNLLJZ47ZVL1w%3d%3d&hdntl=exp=1597650826~acl=%2f*~data=hdntl~hmac=9a46c5ffe594c611b03e0dfbd8e5981aab024fae8492abc40f0fcd7c854af59a

I'm using this regex to get the maximum resolution which is the last URL "https://URL/index_6_av.m3u8?".

(https.*\w*index_6\w*.*)"

My question is, if the "index_6 which is 720p" is not found, how I can get the "index_5" instead so that the result is not empty?

1 Answers

You may use the following pattern:

^https.*index_\d+.*\Z

Demo.

What's changed:

  • Replaced the 6 with \d+ which will match one or more digits.

  • Added \Z (i.e., End of String Anchor) at the end to only match the very last occurrence.

  • The capturing group is redundant so it was removed.

  • The two \w* also seem redundant (because they're either followed or preceded by .*). You may add more restrictions if you need them.


Note: The solution above will only work if the indices are in ascending order. It's mentioned in the question that it should match the last URL so I'm assuming they are in order. If that's not the case, you could write something like this instead:

var matches = Regex.Matches(input, @"^https.*index_(\d{1,9}).*$", RegexOptions.Multiline);
if (matches.Count > 0)
{
    var targetMatch = matches
                      .OfType<Match>()
                      .OrderByDescending(m => int.Parse(m.Groups[1].Value))
                      .First();
    string targetUrl = targetMatch.Value;
}
Related