我正在尝试编写一些代码,以查找以下内容:
Yesterday
Last 7 Days
Last 30 Days
This Year
Last Year
我有以下正则表达式:
/yesterday|(\d+)(?=\s+(\w+))|(\w+)(?=\s+(year))/i
使用:
preg_match("/yesterday|(\d+)(?=\s+(\w+))|(\w+)(?=\s+(year))/i", $input, $output)
我使用phpliveregex.com和preg_match获得以下结果:
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
我的问题是'年'选项以及他们有空键的事实,因为我想引用$output[1]
和$output[2]
来获取间隔和'span'(天)。一次只传递一个字符串,因此它将是上面列出的选项之一,而不是一次查找的多个选项。
如果有人能帮我找到最佳解决方案,可以返回'昨天'或('7'和'天')或('30'和'天')或''这'和'年')或''最后'和'年')非常感谢!
修改
这是我想要的输出:
'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'
我正在尝试捕获处理其余代码所必需的“组”。
答案 0 :(得分:1)
您刚才描述的内容可以通过以下正则表达式实现:
(yesterday|\d+(?=\s+\w+)|\w+(?=\s+year))\s*(\w*)$
在Regex101.com Demo Here上测试:
答案 1 :(得分:1)
您可以使用branch reset功能来避免空组:
$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
模式细节:
\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)
结果:
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
)
)
请注意,在构建分支重置时,必须从没有组的备选项开始,然后从具有一个组的备选项开始,然后是两个组,等等。否则,您可能会在结果中获得无用的空组。
另请注意,组0实际上不是捕获组,但它是整个匹配。
答案 2 :(得分:0)
您可以使用:
/((?:Last|This)\s+(?:\d+\s+Days|Year)|Yesterday)/
匹配
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`
正则表达式演示:
https://regex101.com/r/mA8jZ5/1
正则表达式解释:
/((?: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)