草庐IT

php - 匹配不区分大小写的带空格的精确短语

coder 2024-04-20 原文

如果我有一个字符串 "Hello I went to the store today" 并且我有一个匹配数组

$perfectMatches = array("i went","store today");

它应该匹配这两个。 (数组可能会变得非常大,所以我更愿意在 1 个 preg_match 中完成)

编辑:让这个工作!谢谢!

preg_match_all("/\b(" . implode($perfectMatches,"|") . ")\b/i", $string, $match1)

我还需要一个很难解释的单独的正则表达式。假设我有一个数组

$array = array("birthday party","ice cream");//this can be very long

是否有可能得到一个正则表达式来匹配字符串 if "birthday"和 "party"以及字符串中的任何位置?

所以它应该匹配“嗨,今天是我的生日,我要开个派对”?但是在 1 个 preg_match 中也有“冰淇淋”?

谢谢

编辑:示例...

一个用户提交了一个项目的描述,我想检查垃圾邮件。我知道大多数垃圾邮件帖子都有“个人支票”或“特价”之类的短语,所以我想获得所有这些短语的列表并根据描述进行检查。如果描述包含我列表中的任何短语,它将被标记为垃圾邮件。这种情况适用于我想要的第一个正则表达式。

第二个正则表达式是,如果我知道一些垃圾帖子在某处有“减肥”“减肥”“快速”等词,不必按任何顺序排列,但是这 3 个词在描述中.因此,如果我得到这些短语“快速减肥”、“需要信用卡”的列表并将其与描述核对,我可以将其标记为垃圾邮件

最佳答案

听起来你的问题的第 1 部分已经解决了,所以这个答案只关注第 2 部分。据我了解,你正在尝试确定给定的输入消息是否包含以任何顺序排列的所有单词列表。

这可以通过正则表达式和对每条消息的单个 preg_match 来完成,但如果您有大量单词,则效率非常低。如果 N 是您要搜索的单词数,M 是消息的长度,那么算法应该是 O(N*M)。如果您注意到,每个 关键字的正则表达式中有两个.* 项。使用先行断言,正则表达式引擎必须为每个关键字遍历一次。这是示例代码:

<?php

// sample messages
$msg1 = "Lose all the weight all the weight you want.  It's fast and easy!";
$msg2 = 'Are you over weight? lose the pounds fast!';
$msg3 = 'Lose weight slowly by working really hard!';

// spam defining keywords (all required, but any order).
$keywords = array('lose', 'weight', 'fast');

//build the regex pattern using the array of keywords
$patt = '/(?=.*\b'. implode($keywords, '\b.*)(?=.*\b') . '\b.*)/is';

echo "The pattern is: '" .$patt. "'\n";
echo 'msg1 '. (preg_match($patt, $msg1) ? 'is' : 'is not') ." spam\n";
echo 'msg2 '. (preg_match($patt, $msg2) ? 'is' : 'is not') ." spam\n";
echo 'msg3 '. (preg_match($patt, $msg3) ? 'is' : 'is not') ." spam\n";
?>

输出是:

The pattern is: '/(?=.*\blose\b.*)(?=.*\bweight\b.*)(?=.*\bfast\b.*)/is'
msg1 is spam
msg2 is spam
msg3 is not spam

第二个解决方案似乎更复杂,因为代码更多,但正则表达式要简单得多。它没有先行断言,也没有 .* 条款。 preg_match 函数在 while 循环中调用,但这并不是什么大问题。每条消息只遍历一次,复杂度应该是O(M)。这也可以通过单个 preg_match_all 函数完成,但是您必须执行 array_search 才能获得最终计数。

<?php

// sample messages
$msg1 = "Lose all the weight all the weight you want.  It's fast and easy!";
$msg2 = 'Are you over weight? lose the pounds fast!';
$msg3 = 'Lose weight slowly by working really hard!';

// spam defining keywords (all required, but any order).
$keywords = array('lose', 'weight', 'fast');

//build the regex pattern using the array of keywords
$patt = '/(\b'. implode($keywords,'\b|\b') .'\b)/is';

echo "The pattern is: '" .$patt. "'\n";
echo 'msg1 '. (matchall($patt, $msg1, $keywords) ? 'is' : 'is not') ." spam\n";
echo 'msg2 '. (matchall($patt, $msg2, $keywords) ? 'is' : 'is not') ." spam\n";
echo 'msg3 '. (matchall($patt, $msg3, $keywords) ? 'is' : 'is not') ." spam\n";

function matchall($patt, $msg, $keywords)
{
  $offset = 0;
  $matches = array();
  $index = array_fill_keys($keywords, 0);
  while( preg_match($patt, $msg, &$matches, PREG_OFFSET_CAPTURE, $offset) ) {
    $offset = $matches[1][1] + strlen($matches[1][0]);
    $index[strtolower($matches[1][0])] += 1;
  }
  return min($index);
}
?>

输出是:

The pattern is: '/(\blose\b|\bweight\b|\bfast\b)/is'
msg1 is spam
msg2 is spam
msg3 is not spam

关于php - 匹配不区分大小写的带空格的精确短语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15124922/

有关php - 匹配不区分大小写的带空格的精确短语的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  3. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  4. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  5. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  6. ruby - rbenv 安装 ruby​​ 校验和不匹配 osx - 2

    我已经在mountainlion上成功安装了rbenv和ruby​​build。运行rbenvinstall1.9.3-p392结束于:校验和不匹配:ruby-1.9.3-p392.tar.gz(文件已损坏)预期f689a7b61379f83cbbed3c7077d83859,得到1cfc2ff433dbe80f8ff1a9dba2fd5636它正在下载的文件看起来没问题,如果我使用curl手动下载文件,我会得到同样不正确的校验和。有没有人遇到过这个?他们是如何解决的? 最佳答案 tl:博士;使用浏览器从http://ftp.rub

  7. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

  8. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  9. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  10. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

随机推荐