PHP正则表达式不正确

PHP正则表达式不正确,php,regex,Php,Regex,我试图从父字符串中提取所有看起来像12-15的字符串。这意味着所有在两个数字之间有破折号的字符串 以答案为基础,我尝试了以下方法: <?php $str = "34,56,67-90,45"; preg_match('/^(\d-\d)|(,\d-\d)|(\d-\d,)|(,\d-\d,)$/', $str, $output, PREG_OFFSET_CAPTURE); echo print_r($output); ?> 这将查找在数字之间包含破折号的任何子字符串,无论其前面

我试图从父字符串中提取所有看起来像12-15的字符串。这意味着所有在两个数字之间有破折号的字符串

以答案为基础,我尝试了以下方法:

<?php

$str = "34,56,67-90,45";
preg_match('/^(\d-\d)|(,\d-\d)|(\d-\d,)|(,\d-\d,)$/', $str, $output, PREG_OFFSET_CAPTURE);
echo print_r($output);

?>
这将查找在数字之间包含破折号的任何子字符串,无论其前面、后面或两者都有逗号,还是没有。当我运行PHP代码时,我得到一个空数组。在Regex101上,当我测试正则表达式时,像4-5、、、、、、、这样的字符串似乎是,我不明白为什么它允许我添加额外的逗号


我的正则表达式有什么问题,我得到了一个空数组?

我想你可以使用这样一个简单的正则表达式

\d+[-]\d+

这是至少1个数字的匹配文字破折号至少1个数字的匹配我想你可以用这样一个简单的正则表达式

\d+[-]\d+
即匹配至少1个数字匹配文字破折号匹配至少1个数字匹配单个数字。示例字符串中的所有数字都有两位数。您应该使用\d+匹配任意数量的数字

preg_match('/^(\d+-\d+)|(,\d+-\d+)|(\d+-\d+,)|(,\d+-\d+,)$/', $str, $output, PREG_OFFSET_CAPTURE);
输出:

Array
(
    [0] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

    [1] => Array
        (
            [0] => 
            [1] => -1
        )

    [2] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

)
Array
(
    [0] => Array
        (
            [0] => ,67-90,
            [1] => 5
        )

)
您还可以简化regexp:

preg_match('/(?:^|,)\d+-\d+(?:,|$)/', $str, $output, PREG_OFFSET_CAPTURE);
输出:

Array
(
    [0] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

    [1] => Array
        (
            [0] => 
            [1] => -1
        )

    [2] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

)
Array
(
    [0] => Array
        (
            [0] => ,67-90,
            [1] => 5
        )

)
\d匹配一个数字。示例字符串中的所有数字都有两位数。您应该使用\d+匹配任意数量的数字

preg_match('/^(\d+-\d+)|(,\d+-\d+)|(\d+-\d+,)|(,\d+-\d+,)$/', $str, $output, PREG_OFFSET_CAPTURE);
输出:

Array
(
    [0] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

    [1] => Array
        (
            [0] => 
            [1] => -1
        )

    [2] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

)
Array
(
    [0] => Array
        (
            [0] => ,67-90,
            [1] => 5
        )

)
您还可以简化regexp:

preg_match('/(?:^|,)\d+-\d+(?:,|$)/', $str, $output, PREG_OFFSET_CAPTURE);
输出:

Array
(
    [0] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

    [1] => Array
        (
            [0] => 
            [1] => -1
        )

    [2] => Array
        (
            [0] => ,67-90
            [1] => 5
        )

)
Array
(
    [0] => Array
        (
            [0] => ,67-90,
            [1] => 5
        )

)
|具有优先权,这意味着您的表达式被解释为匹配以下任一项:

文本开头->1位->破折号->1位与文本结尾不匹配 逗号可能在文本的中间,在任何地方- > 1位数字>破折号> 1位数字。 1位任意位置->破折号->1位->逗号 逗号任意位置->1位->破折号->1位->逗号->文本结尾 此外,您使用的\d仅与一个字符匹配一位数字。您可以使用\d{2}匹配2位00到99,或使用\d+匹配任何整数1、55、123456等

在你的情况下,我想你是想用这个表达:

/(?:^|,)(\d+-\d+)(?=,|$)/
这意味着:文本的开头或逗号->任意整数->破折号->任意整数->后跟但不使用逗号或文本的结尾

的|具有优先权,这意味着您的表达式被解释为匹配以下任一项:

文本开头->1位->破折号->1位与文本结尾不匹配 逗号可能在文本的中间,在任何地方- > 1位数字>破折号> 1位数字。 1位任意位置->破折号->1位->逗号 逗号任意位置->1位->破折号->1位->逗号->文本结尾 此外,您使用的\d仅与一个字符匹配一位数字。您可以使用\d{2}匹配2位00到99,或使用\d+匹配任何整数1、55、123456等

在你的情况下,我想你是想用这个表达:

/(?:^|,)(\d+-\d+)(?=,|$)/

这意味着:文本或逗号的开头->任意整数->破折号->任意整数->后跟但不使用逗号或文本的结尾

为什么要在同一行上使用echo和print\r?print\u r已经打印了数组,您不需要调用echo。@Barmar这是一个错误,我通常在print\u r之后添加true为什么您在同一行上使用echo和print\r?print\u r已经打印了数组,您不需要调用echo。@Barmar这是一个错误,我通常在print\u r之后添加true,我如何将模式的所有实例提取到数组中?使用preg\u match\u ALL而不是preg\u match。preg\u match\u ALL的标志有点混乱。我只是想要一个数组,在这个数组中,我可以使用父字符串中找到的匹配项进行迭代。似乎,如果我使用标志PREG_PATTERN_ORDER并进行PREG_match_all$str、$output、PREG_PATTERN_ORDER$输出[0]是我要查找的数组。我做了一些测试,它们似乎是一致的。确定一下,我说的对吗?是的,没错。我同意,选项有点混乱,我永远记不起默认的方式是哪种。当存在连续的数字对34,56,67-90,34-53,24-23时,正则表达式失败。我如何将模式的所有实例提取到数组中?使用preg_match_ALL而不是preg_match。preg_match_的标志都有点混乱。我只是想要一个数组,在这个数组中,我可以使用父字符串中找到的匹配项进行迭代。似乎,如果我使用标志PREG_PATTERN_ORDER并进行PREG_match_all$str、$output、PREG_PATTERN_ORDER$输出[0]是我要查找的数组。我做了一些测试,它们似乎是一致的。确定一下,我说的对吗?是的,没错。我同意,选项有点混乱,我永远记不起哪种方式是默认方式。当有连续的数字对34,56,67-90,34-53,24-23时,正则表达式失败。当有连续的数字对34,56,67-90,34-53,24-23时,正则表达式失败。我被用preg_match而不是preg_match_all误导了。在回答中进行了编辑,具有前瞻性。Thanksy如果存在连续的数字对34,56,67-90,34-53,24-23 true,则正则表达式将失败。我被用preg_match而不是preg_match_all误导了。在回答中进行了编辑,具有前瞻性。谢谢