从格式为“/dmY/H:i/”的字符串中提取日期和时间值或“/dmY/”
解释我的问题的最好方法就是向您展示。
输入字符串:
/04-11-2010/12:45/
获取日期和时间部分的正则表达式:
preg_match('@/(\d\d)-(\d\d)-(\d\d\d\d)/(\d\d):(\d\d)/@', $input, $matches);
PHP 匹配数组:
Array
(
[0] => /01-11-2010/12:45/
[1] => 01
[2] => 11
[3] => 2010
[4] => 12
[5] => 45
)
现在,上面的正则表达式可以完美地获取各个组成部分:表示输入字符串中的日期和时间。
问题是时间部分需要是可选的,而不需要删除整个正则表达式。
问题输入字符串:
/04-11-2010//
PHP 匹配数组
Array
(
)
基本上,匹配数组需要返回的是:
Array
(
[0] => /01-11-2010/12:45/
[1] => 01
[2] => 11
[3] => 2010
[4] =>
[5] =>
)
注意数组元素 4 和 5 仍然需要存在,但返回空。
The best way to explain my problem is to just show you.
Input String:
/04-11-2010/12:45/
Regular Expression to get date and time parts:
preg_match('@/(\d\d)-(\d\d)-(\d\d\d\d)/(\d\d):(\d\d)/@', $input, $matches);
PHP Matches Array:
Array
(
[0] => /01-11-2010/12:45/
[1] => 01
[2] => 11
[3] => 2010
[4] => 12
[5] => 45
)
Now the above regex works perfectly at getting the individual component parts that represent the date and time in the input string.
The problem is that the time part needs to be optional without bringing down the entire regular expression.
Problem Input String:
/04-11-2010//
PHP Matches Array
Array
(
)
Basically what I need to be returned by the matches array is:
Array
(
[0] => /01-11-2010/12:45/
[1] => 01
[2] => 11
[3] => 2010
[4] =>
[5] =>
)
Note array elements 4 and 5 still need to exist but return empty.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用问号运算符和非捕获组使内容成为可选。
我不确定它如何与匹配数组交互 - 如果空数组元素绝对重要,您可能需要选择
Which 有其自己的误报(当时的冒号现在是可选的)。
Use the question mark operator and a non-capturing group to make stuff optional.
I'm not sure how this interacts with the match array - if having the empty array elements is absolutely critical, you might need to instead go for
Which has its own false-positives (the colon in the time is now optional).
将第二部分设为可选:
此处使用无法引用的非捕获组
(?:…)
,因此不会更改匹配组。Make the second part optional:
Here a non-capturing group
(?:…)
is used that cannot be referenced and thus doesn’t change the matching groups.做你想做的事(即填充第 4 组和第 5 组),但也接受不完整的时间,例如
不知道这对你来说是否合适
does what you want (i.e. populates groups 4 and 5), but also accepts incomplete times like in
don't know if this is fine with you
我不是 php-head,但是怎么样:
就正则表达式而言,它应该匹配没有时间字段的字符串。
I'm not a php-head, but how about:
As far as regexps go, that should match a string that has no time field.
@OP,不需要混乱的正则表达式。
@OP, don't need messy regex.
使用本机 PHP 函数来完成此任务,使用正则表达式有点大材小用。
PHP 5 有 date_parse 函数:
输出:
PHP 5.3 有更灵活的 date_parse_from_format 函数,您可以也用。
Use native PHP functions for this task, using regular expressions is a bit of an overkill.
PHP 5 has the date_parse function:
Output:
PHP 5.3 has a more flexible date_parse_from_format function that you could also use.
我将演示一些从时间可选的 DateTime 表达式中解析或提取数据的工作技术。请参阅此演示以获取其输出的证明。
解析日期/日期时间表达式的首要考虑因素应该是合法的日期时间解析器。仅当您有令人信服的理由时才偏离此选择。
在这种情况下,在确定动态表达式是否具有时间分量后解析该动态表达式。无论哪种方式,请在格式参数的末尾添加一个管道,以将任何缺失的日期时间值清零。这将创建一个对象而不是数组,但根据您的下一步,这可能是从中提取值的理想来源
<前><代码>var_export(
日期时间::createFromFormat(
str_contains($test, ':')
? '/dmY/H:i/|'
: '/dmY//|',
$测试
)
);
提取值的理想来源
对于填充所需数组的最直接方法,
sscanf()
是可行的,因为可选组件位于字符串的末尾。如果未遇到尾随时间值,它们将作为null
元素返回。<前><代码>var_export(
sscanf(
$测试,
'/%02s-%02s-%04s/%02[^/:]:%02[^/:]'
)
);
输入到
preg_split()
的一个或多个非数字字符的正则表达式在人眼看来非常容易,并返回一个平面数组,但需要用null< 填充/code> 当输入字符串中未提供元素时的时间元素。
<前><代码>var_export(
数组垫(
预分割(
'/\D+/',
$测试,
0,
PREG_SPLIT_NO_EMPTY
)
5、
无效的
),
);
preg_match()
对于具有基本正则表达式技能的开发人员来说可能是一个舒适的调用,如果需要验证,它比preg_split()
有优势,但它的输出是包含必须移走的完整字符串匹配的引用变量。将时间表达式设为可选,并设置PREG_UNMATCHED_AS_NULL
标志,以便在缺少时间值时获得null
元素。<前><代码>var_export(
预匹配(
'#/(\d{2})-(\d{2})-(\d{4})/(?:(\d{2}):(\d{2})/)?#' ,
$测试,
$匹配,
PREG_UNMATCHED_AS_NULL
)
? array_slice($匹配项, 1)
:[]
);
最后,最没有吸引力的选项是对字符串进行标记。不仅在此 IIFE 内部使用循环来进行迭代
strtok()
调用,返回的数组仍然需要附加null
时间元素。这简直就是丑陋。<前><代码>var_export(
(函数($代币){
while ($t = strtok('/:-')) {
$tokens[] = $t;
}
返回 $tokens + [3 =>空,4 =>无效的];
})([strtok($test, '/:-')])
);
I'll demonstrate a few working techniques to parse or extract data from your time-optional DateTime expressions. See this demo for proof of their output.
The first consideration for parsing date/datetime expressions should be a legitimate datetime parser. Only deviate from this choice if you have a compelling reason.
In this case, parse the dynamic expression after determining if it has a time component. Either way, add a pipe to the end of the format parameter to zero-out any missing datetime values. This creates an object instead of an array, but depending on your next step, this may be an ideal source to extract values from
For the most direct approach to populate the desired array,
sscanf()
is viable because the optional components are at the end of the string. The trailing time values will be returned asnull
elements if they are not encountered.A regular expression of one or more non-digital characters fed to
preg_split()
is very easy on human eyes and returns a flat array, but will need to be padded withnull
time elements when they are not supplied in the input string.preg_match()
may be a comfortable call for developers with basic regex skills and it has the advantage overpreg_split()
if validation is required, but its output is a reference variable which includes the full string match which must be shifted off. Make the time expression optional and set thePREG_UNMATCHED_AS_NULL
flag to gainnull
elements when missing time values.And finally, the least attractive option is to tokenize the string. Not only is a loop used inside of this IIFE to make iterated
strtok()
calls, the returned array still needs to appendnull
time elements. It's just plain fugly.