使用preg_match解析表达式

时间:2011-01-04 11:57:28

标签: php regex preg-match match

我正在尝试使用preg_match解析以下内容:

2020|9 digits number|date hour|word|word

举个例子:

2020|123456789|01/04/2011 09:09:37|Basketball|sms

我在做:

$regex  = '2020|/[0-9]+\|[a-zA-Z]+\|[0-9]{2}\/[0-9]{2}\/[0-9]{4}.*/';
return !(preg_match($regex,$value));

但是我收到错误Delimiter must not be alphanumeric or backslash,而我甚至没有接近它。

你可以帮我一把吗?

3 个答案:

答案 0 :(得分:7)

如果|是您的分隔符,并且数据始终按照您描述的方式进行结构化,那么为什么不使用explode()

$array = explode ("|", $value);
echo $array[0]; // Will output "2020"
echo $array[1]; // Will output "123456789"

为了使其可靠地工作,所有列都不得包含“|”作为内容角色。但你也有正则表达式的限制。

如果您正在解析像这样构建的整个文件,请查看fgetcsv()

答案 1 :(得分:3)

你的正则表达式有一些问题

  • 逃离第一个|
  • 将第一个/移到正则表达式的开头。 /是一个分隔符,用于标记正则表达式的开头和结尾。
  • 删除[a-zA-Z]+,因为它与您的定义没有的字匹配。

这应该有效:

$regex  = '/2020\|[0-9]+\|[0-9]{2}\/[0-9]{2}\/[0-9]{4}.*/';
return !(preg_match($regex,$value));

您还可以使用#作为分隔符,以避免需要转义文字/

$regex  = '#2020\|[0-9]+\|[0-9]{2}/[0-9]{2}/[0-9]{4}.*#';

它也不像你对字符串应该是什么样的定义那么严格。我建议做出以下改进:

  • 使用[0-9]{9}匹配9位数字,而不是1位数。
  • 将时间戳与[0-9]{2}:[0-9]{2}:[0-9]{2}匹配。
  • 将最后两个单词与\w+\|\w+匹配。
  • 添加^$个锚点以强制匹配完整字符串。

将所有这些放在一起给了我们:

$regex  = '#^2020\|[0-9]{9}\|[0-9]{2}/[0-9]{2}/[0-9]{4}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\|\w+\|\w+$#';

on rubular

答案 2 :(得分:1)

Perl兼容的正则表达式必须以分隔符开头和结尾(下面是%)。您的RE以“2”开头,PCRE将其解释为分隔符,因此“分隔符不能是字母数字或反斜杠”错误。

我开始检查“2020 | 9位数|日期小时|单词|单词”的表达式是%^2020\|\d{9}\|\d{2}[-/]\d{2}[-/]\d{4} \d{2}:\d{2}:\d{2}\|\w+\|\w+$%。除日期外,与字段匹配的RE非常简单:预定义的类(\d表示数字,相当于[0-9]; \w表示单词,相当于[A-Za-z0-9_])重复({n}表示 n +表示1或更多)。

日期与\d{2}[-/]\d{2}[-/]\d{4} \d{2}:\d{2}:\d{2}匹配。它使用与其他子模式相同的元素,只有更多的子模式。如果您想匹配更多日期格式,您需要编写更复杂的RE,或者提取日期并使用(例如)strtotime来解析它。

如果你想解析整个字符串,而不是简单地检查它,请按照Pekka的建议。