正则表达式匹配终止符加上可变字符序列

Sorry to bother, I feel permanently lost when it comes to regex...

I have to match a string which occurs in a longer sequence of hex-values. My test-string is this:

BF1301020302000017BF1301030101010300FF6ABF130201010300FFC0BF1303010303030100FF98

Pattern is this:

  • starts with BF13
  • followed by an unknown amount of "01", "02" or "03" repetitions (\w\w)
  • 00 marks the termination of the sequence between BF13 and 00
  • after the 00-terminator, there are always 4 additional chars

I tried BF13(\w\w)+?00(\w\w){1} but it's obviously wrong.

The test-string is supposed to match and output these values:

  • BF1301020302000017
  • BF1301030101010300FF6A
  • BF130201010300FFC0
  • BF1303010303030100FF98

Thanks, guys!

This one will do the job :

BF13(?:0[123])+00[A-Z0-9]{4}

Explanation

BF13 BF13 literally

(?:...)+ Followed by something (non capturing group) at least one time (+)

0[123] a zero followed by 1, 2 or 3

00 Followed by 00

[A-Z0-9]{4} Followed by uppercase char or a digit 4 times

RegExp Demo

Sample PHP code Test online

$re = '/BF13(?:0[123])+00[A-Z0-9]{4}/';
$str = 'BF1301020302000017BF1301030101010300FF6ABF130201010300FFC0BF1303010303030100FF98';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

foreach ($matches as $val) {
    echo "matched: " . $val[0] . "
";
}

You have a couple of options:

Input:

$in='BF1301020302000017BF1301030101010300FF6ABF130201010300FFC0BF1303010303030100FF98';

Method #1 - preg_match_all() (Regex Pattern Explanation/Demo):

var_export(preg_match_all('/BF13(?:0[123])+0{2}[A-F0-9]{4}/',$in,$out)?$out[0]:[]);
// *my pattern is a couple of steps faster than stej4n's
// and doesn't make the mistake of putting commas in the character class

Method #2: - preg_split() (Regex Pattern Explanation/Demo):

var_export(preg_split('/0{2}[A-F0-9]{4}\K/',$in,null,PREG_SPLIT_NO_EMPTY));
// K moves the match starting point -- preserving all characters when splitting
// I prefer this method because it requires a small pattern and
// it returns an array, as opposed to true/false with a variable declaration
// Another pattern for preg_split() is just slightly slower, but needs less parameters:
// preg_split('/0{2}[A-F0-9]{4}\K(?!$)/',$in)

Output (either way):

array (
  0 => 'BF1301020302000017',
  1 => 'BF1301030101010300FF6A',
  2 => 'BF130201010300FFC0',
  3 => 'BF1303010303030100FF98',
)