Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP preg_match()-如何排除单词?_Php_Regex - Fatal编程技术网

PHP preg_match()-如何排除单词?

PHP preg_match()-如何排除单词?,php,regex,Php,Regex,我正在使用PHP preg_match()检查一些给定的单词是否在字符串中。 例如,字符串: I have not failed. I've just found 10,000 ways that won't work. 我的正则表达式是从HTML表单动态构建的,看起来像: /(apple)|(banana)|(work)/i 在本例中,我们有一个匹配项,但是如果字符串包含“ways”,我希望不匹配。 我试过: 苹果香蕉工作? 但它也返回1(匹配) 我应该向正则表达式中添加什么以使其与字符串

我正在使用PHP preg_match()检查一些给定的单词是否在字符串中。 例如,字符串:

I have not failed. I've just found 10,000 ways that won't work.
我的正则表达式是从HTML表单动态构建的,看起来像:

/(apple)|(banana)|(work)/i
在本例中,我们有一个匹配项,但是如果字符串包含“ways”,我希望匹配。 我试过:

苹果香蕉工作? 但它也返回1(匹配) 我应该向正则表达式中添加什么以使其与字符串示例不匹配

谢谢你的帮助。

code
<?php 
$your_word = 'way'; // return work
// $your_word = 'ways'; // return null

preg_match('/(ways)/i',"I have not failed. I've just found 10,000 $your_word that won't work.",$x);

if(isset($x[0])=='ways'){ 
    null;
}else{ 
    preg_match('/(apple)|(banana)|(work)/i',"I have not failed. I've just found 10,000 ways that won't work.",$z);
    echo $z[0];
}   

?>
我有以下两种方法可以解决你的问题

方法1 此方法使用捕获组捕获要匹配的单词

方法2 这个方法不捕获任何东西,它只是匹配。这会在单词匹配之前重置模式


结果 我使用了两个字符串进行测试。第一个包含单词
ways
,第二个不包含(我删除了
s
,因此它包含
way

输入 输出 因为如果我只是将其粘贴到这里,输出实际上会引起更多的混乱,所以我只告诉您,它匹配第二个字符串中的
work
banana
、和
apple
,而不是第一个字符串(因为第一个字符串包含否定词
ways


解释 我将解释第二种方法,因为这两种方法非常相似,但是第二种方法使用了一个额外的标记

  • (?:(?:^(?。*\b天\b天)|\G(?!\A)).?
    匹配以下内容
    • (?:^(?。*\b天\b)|\G(?!\A))
      匹配以下任一项
      • ^(?。*\b天\b)
        匹配以下内容
        • ^
          在行首断言位置
        • (?!.\bways\b)
          消极前瞻确保单词
          方式
          不跟随(
          \b
          是单词边界断言,因此我们不会匹配包含
          方式
          的单词,例如
          始终
          路边
          ,如您问题下方的注释所述)
      • \G(?!\A)
        在上一次匹配结束时断言位置
    • *?
      匹配任意字符任意次数,但尽可能少
  • \K
    重置报告匹配的起始点。任何以前使用的字符不再包括在最终匹配中
  • \b(?:apple | banana | work)\b
    逐字匹配组中的任何单词
    apple
    banana
    、或
    work
    ,同时确保其单词边界(以免与包含这些单词的单词不匹配,例如
    菠萝
    工作场所

您可以使用
/^(?。*\b天].*?(?:apple | banana | work)/i
检查字符串之前是否包含“方式”。如果是,甚至不要尝试您的模式。(同时删除无用的捕获组)。注意不要使用分词来匹配单词,否则你可能会发现
ways
也会匹配像
always
wayside
这样的单词。谢谢你的回复。我会尝试不同的方法。anubhava的方法似乎更容易动态构建。请发布你的php代码,让我们看看你是如何使用的e动态构建。您是否需要担心在
允许的
禁忌的
字符串中转义字符?我想看看您是如何构建模式的--我们可以帮助您解决一些常见的陷阱。为什么ctwheels的模式太难实现?
<?php 
$your_word = 'way'; // return work
// $your_word = 'ways'; // return null

preg_match('/(ways)/i',"I have not failed. I've just found 10,000 $your_word that won't work.",$x);

if(isset($x[0])=='ways'){ 
    null;
}else{ 
    preg_match('/(apple)|(banana)|(work)/i',"I have not failed. I've just found 10,000 ways that won't work.",$z);
    echo $z[0];
}   

?>
(?:(?:^(?!.*\bways\b)|\G(?!\A)).*?)\b(apple|banana|work)\b
(?:(?:^(?!.*\bways\b)|\G(?!\A)).*?)\K\b(?:apple|banana|work)\b
I have not failed. I've just found 10,000 ways that won't work. A banana and an apple
I have not failed. I've just found 10,000 way that won't work. A banana and an apple