Php 预匹配排除字符串

Php 预匹配排除字符串,php,regex,preg-match,Php,Regex,Preg Match,从10000行数据中,我必须得到所有不包含以“en”或“it”或“de”等开头的单词的行,它们的a-z和a-z长度从2到5,也有“-”(减号)和“;” 我试过了,但没用 !preg_match("/\b(it|en|de|es|fr|ru)[a-zA-Z-;]{2,5}/", $value) (对我来说)这是不匹配的所有行都有以它开头的单词,en等由2到5个字符组成,在这5个字符中还可以包含“-”或“;” 这将返回带有“it”的行,我需要排除这些行 编辑:我需要匹配以这两个字符开头的每个单词

从10000行数据中,我必须得到所有包含以“en”或“it”或“de”等开头的单词的行,它们的a-z和a-z长度从2到5,也有“-”(减号)和“;”

我试过了,但没用

 !preg_match("/\b(it|en|de|es|fr|ru)[a-zA-Z-;]{2,5}/", $value)
(对我来说)这是不匹配的所有行都有以它开头的单词,en等由2到5个字符组成,在这5个字符中还可以包含“-”或“;”

这将返回带有“it”的行,我需要排除这些行

编辑:我需要匹配以这两个字符开头的每个单词(it、en或de),并且可以在行中的任何位置

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

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


您正在寻找的魔法字符是插入符号:
^

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

除此之外,看起来还不错。

您正在寻找的魔法角色是插入符号:
^

!preg_match("/^(it|en|de|es|fr|ru)[a-zA-Z-;]{2,5}/", $value)
除此之外,看起来不错。

您可以使用:

此处,
(?!…)
断言,如果不实际匹配包含模式,则包含模式从当前位置开始不得存在匹配。

您可以使用:


此处,
(?!…)
断言,如果不实际匹配包含模式,则从当前位置开始的包含模式不得匹配。

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

$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
元字符的使用应该正确<代码>\b如果第一个字符是单词字符,则在字符串开头匹配

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


我假设您的数据被一个
\n
(换行符)字符分割成几行。它可能被
\r
\n\r
拆分。如果您不知道使用了哪些换行符,可以使用代替,即:


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

$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
元字符的使用应该正确<代码>\b如果第一个字符是单词字符,则在字符串开头匹配

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


我假设您的数据被一个
\n
(换行符)字符分割成几行。它可能被
\r
\n\r
拆分。如果您不知道使用了哪些换行符,可以使用代替,即:


据我所知,您的正则表达式匹配的字符串以一个国家代码开头,总长度为4-7,而不是2-5。So
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
。在这里,我们说“一个以/en/de等开头的单词可能会以破折号和两个字母继续,而(不管它是否有破折号和两个字母)可能会以分号继续。在这个单词结束之前,不允许有任何其他内容。”

据我所知,您的正则表达式匹配以某个国家/地区代码开头且总长度为4-7而不是2-5的字符串。So
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
。在这里,我们说“一个以/en/de等开头的单词可能会以破折号和两个字母继续,并且(不管它是否有破折号和两个字母)可能会以分号继续。在该单词结束之前,不允许有任何其他内容。”

你能给我们看一些你正在匹配的数据吗?你能给我们看一些你正在匹配的数据吗?不太清楚。插入符号匹配行首,但不匹配单词的开头(当然,行首的单词除外)
\b
匹配单词边界(也可能不是单词的开头,因为单词边界只是指
\W
中的字符和
\W
中的字符之间的位置)。这会返回零行,但是有些行的开头是这样的,他说他想忽略以l开头的行
$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.
  }
}
$lines = preg_split('/\n|\n?\r/', $data);