简体   繁体   English

PHP正则表达式匹配多个选项

[英]PHP Regex Matching Multiple Options

I am attempting to write some code that looks for the following: 我正在尝试编写一些查找以下内容的代码:

Yesterday
Last 7 Days
Last 30 Days
This Year
Last Year

I have the following regex: 我有以下正则表达式:

/yesterday|(\d+)(?=\s+(\w+))|(\w+)(?=\s+(year))/i

using: 使用:

preg_match("/yesterday|(\d+)(?=\s+(\w+))|(\w+)(?=\s+(year))/i", $input, $output)

I get the following results using phpliveregex.com with the preg_match: 使用带有preg_match的phpliveregex.com,我得到以下结果:

array(5
0   =>  Last
1   =>  
2   =>  
3   =>  Last
4   =>  Year
)
array(5
0   =>  This
1   =>  
2   =>  
3   =>  This
4   =>  year
)
array(1
0   =>  yesterday
)
array(3
0   =>  30
1   =>  30
2   =>  days
)
array(3
0   =>  7
1   =>  7
2   =>  days

My issue is with the 'Year' options and the fact that they have empty keys because I want to refer to $output[1] and $output[2] to get the interval and 'span' (days). 我的问题是“年份”选项和它们具有空键的事实,因为我想引用$output[1]$output[2]来获取间隔和“跨度”(天)。 Only a single string will be passed at a time so it will be one of the options listed above and not multiple options to look for at once. 一次只传递一个字符串,因此它将是上面列出的选项之一,而不是一次查找的多个选项。

If anyone can help me find the best solution to return 'yesterday' or ('7' and 'days') or ('30' and 'days') or ('This' and 'Year') or ('Last' and 'Year') I would appreciate it very much! 如果有人可以帮助我找到最好的解决方案,以返回“昨天”或“(7”和“天”)或(“ 30”和“天”)或(“此”和“年份”)或(“最后”和'年')我将非常感激!

EDIT 编辑

This is my desired output: 这是我想要的输出:

'Yesterday'
$output[0] => 'Yesterday'

'Last 7 Days'
$output[0] => '7'
$output[1] => 'Days'

'Last 30 Days'
$output[0] => '30'
$output[1] => 'Days'

'This Year'
$output[0] => 'This'
$output[1] => 'Year'

'Last Year'
$output[0] => 'Last'
$output[1] => 'Year'

I am trying to capture the 'groups' necessary to process the rest of my code. 我试图捕获处理其余代码所必需的“组”。

What you just described can be Achieved with the following Regex: 您可以使用以下正则表达式来实现您刚刚描述的内容:

(yesterday|\d+(?=\s+\w+)|\w+(?=\s+year))\s*(\w*)$

Tested on Regex101.com Demo Here : 在Regex101.com 演示上进行了测试:

在此处输入图片说明

You can use the branch reset feature to avoid empty groups: 您可以使用分支重置功能来避免出现空组:

$text = <<<'EOD'
Yesterday
Last 7 Days
Last 30 Days
This Year
Last Year
EOD;

$pattern = '~\b(?|yesterday\b|\d+(?= (days\b))|\w+(?= (year\b)))~i';
if (preg_match_all($pattern, $text, $matches, PREG_SET_ORDER))
    print_r($matches);
// or preg_match without PREG_SET_ORDER if you test the strings one by one

pattern details: 图案细节:

\b
(?|                     # open the branch reset group
    yesterday \b        # when this branch succeeds the capture group is not defined
  |
    \d+ (?=[ ](days\b)) # in each branch the capture group
  |
    \w+ (?=[ ](year\b)) # has the same number 
)                       # (so there is only one capture group)

result: 结果:

Array
(
    [0] => Array
        (
            [0] => Yesterday
        )

    [1] => Array
        (
            [0] => 7
            [1] => Days
        )

    [2] => Array
        (
            [0] => 30
            [1] => Days
        )

    [3] => Array
        (
            [0] => This
            [1] => Year
        )

    [4] => Array
        (
            [0] => Last
            [1] => Year
        )

)

Note that when you build the branch reset, you must begin with alternatives that has no groups, then alternatives with one groups, then two groups, etc. otherwise you may obtain useless empty groups in the result. 请注意,在构建分支重置时,必须从没有组的替代项开始,然后从具有一组,然后两组的替代项开始,以此类推。否则,您可能会在结果中获得无用的空组。

Note too that the group 0 isn't really a capture group but it is the whole match. 还要注意,组0并不是真正的捕获组,但它是整个匹配项。

You can use: 您可以使用:

/((?:Last|This)\s+(?:\d+\s+Days|Year)|Yesterday)/

Matches: 火柴:

MATCH 1
1.  [0-9]   `Yesterday`
MATCH 2
1.  [10-21] `Last 7 Days`
MATCH 3
1.  [22-34] `Last 30 Days`
MATCH 4
1.  [35-44] `This Year`
MATCH 5
1.  [45-54] `Last Year`

Regex Demo: 正则表达式演示:

https://regex101.com/r/mA8jZ5/1 https://regex101.com/r/mA8jZ5/1


Regex Explanation: 正则表达式说明:

/((?:Last|This)\s+(?:\d+\s+Days|Year)|Yesterday)/

1st Capturing group ((?:Last|This)\s+(?:\d+\s+Days|Year)|Yesterday)
    1st Alternative: (?:Last|This)\s+(?:\d+\s+Days|Year)
        (?:Last|This) Non-capturing group
            1st Alternative: Last
                Last matches the characters Last literally (case sensitive)
            2nd Alternative: This
                This matches the characters This literally (case sensitive)
        \s+ match any white space character [\r\n\t\f ]
            Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        (?:\d+\s+Days|Year) Non-capturing group
            1st Alternative: \d+\s+Days
                \d+ match a digit [0-9]
                    Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
                \s+ match any white space character [\r\n\t\f ]
                    Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
                Days matches the characters Days literally (case sensitive)
            2nd Alternative: Year
                Year matches the characters Year literally (case sensitive)
    2nd Alternative: Yesterday
        Yesterday matches the characters Yesterday literally (case sensitive)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM