user3325376 user3325376 - 6 months ago 22
PHP Question

get closest match in regex

I am trying to get the closest match between two words in regex

here is an example what I am trying to do:
https://regex101.com/r/kpIJpj/1/

the problem is

"Track number"
will find the first match and continue looking for
"subtitles"


the things I need just grep,

Track number: 3 (track ID for mkvmerge & mkvextract: 2)
| + Track UID: 1382186431
| + Track type: subtitles


so basically grep closest
"Track number"
to the
"subtitles"
word

but i don't know how

Answer Source

For this particular string which you have posted,this will help you out.

Solution 1: Probably this can fail in case when required match is not in end. But second solution fullfill the required result

Regex: .*\KTrack number.*?subtitles

1. .*\KTrack number It will match greedily till it finds Track and \K will reset the match.

2. .*?subtitles This will match all till subtitles

Regex code demo

Solution 2: Tricky solution, for testing purpose i have added a sample string just in the middle to show this solution is working fine.

Try this code snippet here

$string='"
+ EBML head
|+ EBML version: 1
|+ EBML read version: 1
|+ EBML maximum ID length: 4
|+ EBML maximum size length: 8
|+ Doc type: matroska
|+ Doc type version: 2
|+ Doc type read version: 2
+ Segment, size 627752082
|+ Seek head (subentries will be skipped)
|+ EbmlVoid (size: 4044)
|+ Segment information
| + Timecode scale: 1000000
| + Muxing application: libebml v1.0.0 + libmatroska v1.0.0
| + Writing application: mkvmerge v4.1.1 (\'Bouncin\' Back\') built on Jul  3 2010 22:54:08
| + Duration: 7279.440s (02:01:19.440)
| + Date: Sat Sep 18 15:52:16 2010 UTC
| + Segment UID: 0x83 0x63 0x0c 0xd7 0x2c 0xb9 0x73 0xb5 0xab 0x7f 0xd0 0xa4 0x3d 0x1c 0xf9 0xf6
|+ Segment tracks
| + A track
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
|  + Track UID: 1383154402
|  + Track type: video
|  + Lacing flag: 0
|  + MinCache: 1
|  + Codec ID: V_MPEG4/ISO/AVC
|  + CodecPrivate, length 45 (h.264 profile: Main @L3.1)
|  + Default duration: 40.000ms (25.000 frames/fields per second for a video track)
|  + Video track
|   + Pixel width: 1280
|   + Pixel height: 696
|   + Display width: 1280
|   + Display height: 696
| + A track
|  + Track number: 2 (track ID for mkvmerge & mkvextract: 1)
|  + Track UID: 3159569538
|  + Track type: audio
|  + Codec ID: A_AAC
|  + CodecPrivate, length 2
|  + Default duration: 21.333ms (46.875 frames/fields per second for a video track)
|  + Audio track
|   + Sampling frequency: 48000
|   + Channels: 2
| + A track
|  + Track number: 3 (track ID for mkvmerge & mkvextract: 2)
|  + Track UID: 3633586111
|  + Track type: subtitles
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
| + A track
|  + Track number: 4 (track ID for mkvmerge & mkvextract: 3)
|  + Track UID: 1098098602
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: dut
| + A track
|  + Track number: 5 (track ID for mkvmerge & mkvextract: 4)
|  + Track UID: 2228128442
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: fre
| + A track
|  + Track number: 6 (track ID for mkvmerge & mkvextract: 5)
|  + Track UID: 1507679374
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: ita
| + A track
|  + Track number: 7 (track ID for mkvmerge & mkvextract: 6)
|  + Track UID: 3667538853
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: swe
|+ EbmlVoid (size: 1239)
|+ Cluster
';
$result=null;
$matched=false;
for($x=0;$x<substr_count($string, "|");$x++)
{
    preg_match_all("/Track number(?:.*?[\|]){".$x."}/s", $string,$matches);
    foreach($matches[0] as $match)
    {
        if(preg_match_all("/Track number.*?subtitles/s", $match,$matches))
        {
            $result[]=$matches[0];
            $matched=true;
        }
    }
    if($matched==true)
    {
        break;
    }
}
print_r($result);