【问题标题】:Regex matching to a terminator plus a variable character sequence正则表达式匹配一个终止符加上一个可变字符序列
【发布时间】:2017-10-30 03:02:49
【问题描述】:

抱歉打扰了,当谈到正则表达式时,我感到永远迷失......

我必须匹配出现在较长十六进制值序列中的字符串。我的测试字符串是这样的:

BF1301020302000017BF1301030101010300FF6ABF130201010300FFC0BF1303010303030100FF98

图案是这样的:

  • 从 BF13 开始
  • 后跟未知数量的“01”、“02”或“03”重复 (\w\w)
  • 00标志着BF13和00之间序列的终止
  • 在 00 结束符之后,总是有 4 个额外的字符

我试过BF13(\w\w)+?00(\w\w){1},但显然是错误的。

测试字符串应该匹配并输出这些值:

  • BF1301020302000017
  • BF1301030101010300FF6A
  • BF130201010300FFC0
  • BF1303010303030100FF98

谢谢各位!

【问题讨论】:

  • 你的模式有效,你只需要{2}而不是最后的{1},因为总是有4个额外的字符Live test working here
  • 试试这个BF13(0[1-3])+00([0-9A-F]{4})。在这里你匹配 BF13 然后 0(1 or 2 or 3) 1 次或更多次,然后 00 然后 0 到 9 或 A 到 F(区分大小写)4 次。
  • 啊!你是对的@WashingtonGuedes。我忘了在 phpliveregex 中切换到 preg_match_all ......我的错!谢谢!!!
  • @Alex 小心你的正则表达式,你接受任何带有\w 的东西,而不仅仅是010203,所以它不是一个“有效”的正则表达式。
  • 另外,捕获组可能无法捕获您想要的内容。 (注意它捕获了第一部分的0217,而不是0017,这将是最后2个字节)

标签: php regex hex preg-match-all substring


【解决方案1】:

你有几个选择:

输入:

$in = 'BF1301020302000017BF1301030101010300FF6ABF130201010300FFC0BF1303010303030100FF98';

方法 #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

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

var_export(preg_split('/0{2}[A-F0-9]{4}\K/', $in, 0, 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)

输出(无论哪种方式):

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

【讨论】:

  • 感谢您的帮助和解释!在尝试提高我的技能时,这对我很有帮助。正则表达式需要与 preg_match_all 一起使用,因为我正在解析二进制文件并使用一堆其他表达式在我的文件中找到更多类似的内容。总之,好东西!再次感谢!
【解决方案2】:

这个可以完成这项工作:

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

说明

BF13BF13 字面意思

(?:...)+后跟某事(非捕获组)至少一次(+

0[123] 后跟 1、2 或 3 的零

00后面是00

[A-Z0-9]{4}后跟大写字符或数字4次

RegExp Demo

示例 PHP 代码 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] . "\n";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多