preg_match排除字符串

时间:2011-02-26 18:22:06

标签: php regex preg-match

从10,000行数据中,我必须得到包含START“en”或“it”或“de”等字样的所有行,来自2到5长az和AZ也带“ - ”(减号)和“;”

我尝试了这个但是不起作用

 !preg_match("/\b(it|en|de|es|fr|ru)[a-zA-Z-;]{2,5}/", $value)

这将被读取(对我来说)不匹配所有行都有以它开头的单词,en等由2到5个字符组成,在这5个字符中也可以包含“ - ”或“; ”

这会给我回复“it;”我需要排除。

编辑:我需要匹配以这2个字符开头的每个单词( it en de ),并且可以随处可见这条线

要匹配的示例(它不包含以“en”,“de”等开头的单词)

GET; SITE; 15:03:03; ; Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1; .NET4.0C); 

示例不匹配(它包含以“en”开头的单词)

GET; SITE; 13:06:49; ; Mozilla/4.0 (compatible; **en;** MSIE 8.0; Windows NT 6.1; Trident/4.0; SIMBAR={E76F6580-EB92-49A3-A089-F6B8B9DEA9AA}; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; eSobiSubscriber 2.0.4.16; Media Center PC 5.0; SLCC1; .NET4.0C); ; 

4 个答案:

答案 0 :(得分:4)

据我所知,你的正则表达式匹配以一个国家/地区代码开头的字符串,总长度 4 - 7 ,而不是2 - 5.所以en;不匹配,因为它只包含三个符号。 {2,5}仅适用于其左边的表达式,所以你的正则表达式是“一个以它开头的单词/ en / de等,并继续使用两到五个字母/短划线/分号。”试试\b(it|en|de|es|fr|ru)[a-zA-Z-;]{0,3}

您可能还想明确分号是最后一个字符,也许还要更具体地说明ISO语言代码的结构(我假设这些字符串是):\b(it|en|de|es|fr|ru)(-[a-zA-Z]{2})?;?\b。在这里,我们说“一个以it / en / de等开头的单词,可能会以短划线和两个字母继续,并且(无论是否有短划线和两个字母)都可以继续使用分号。其他任何内容都不会出现。在这个词应该结束之前允许。“

答案 1 :(得分:1)

最简单的方法是首先将数据拆分为单独的行,然后一次检查一次:

$lines = explode("\n", $data); // I'm making an assumption here, discussed below.
foreach ($lines as $line)
{
  if (!preg_match('/\b(?=it|en|de|es|fr|ru)[a-z;-]{2,5}/i', $line))
  {
    // line doesn't contain a word beginning with en, de, etc.
  }
}

您对\b word boundary元字符的使用应该正常运行;如果第一个字符是单词字符,则\b匹配字符串的开头。

我正在使用positive lookahead assertion(?=))来检查单词的前两个字符是否是您要查找的语言代码。这避免了@Aasmund Eldhuset在his answer中指出的问题。换句话说,正则表达式引擎会查找以您要排除的语言代码开头的单词,但是匹配的结果会被PHP逻辑反转,因此忽略包含这些单词的所有行。


我假设您的数据被单个\n(换行符)字符拆分为行。它可能会被\r\n\r拆分。如果您不知道正在使用哪个换行符,则可以使用preg_split代替explode,即:

$lines = preg_split('/\n|\n?\r/', $data);

答案 2 :(得分:0)

您正在寻找的神奇角色是插入符:^

!preg_match("/^(it|en|de|es|fr|ru)[a-zA-Z-;]{2,5}/", $value)

除此之外,看起来不错。

答案 3 :(得分:0)

您可以使用look-ahead assertion

/\b(?!it|en|de|es|fr|ru)[a-zA-Z-;]{2,5}/

这里(?!…)声称在没有实际匹配该模式的情况下,当前位置的包含模式必须不匹配。