【问题标题】:Conditional Regex searches条件正则表达式搜索
【发布时间】:2011-08-21 20:39:57
【问题描述】:

我正在尝试在 Java 中创建一个包含条件搜索词的正则表达式代码。

我的意思是假设我有 5 个单词;树,汽车,狗,猫,鸟。现在我想要表达式来搜索这些术语,但是只需要匹配五个中的三个,它可以是它选择匹配的 5 个中的任何一个。

我认为也许使用反向引用 ?(3) 会起作用,但似乎不起作用。

标准的可选搜索 (?) 也不起作用,因为所有术语都是可选的,但所需的匹配数不是。本质上,有没有办法创建一个必须 50%(或任何百分比)正确才能提供匹配的字符串?

有没有人碰巧知道或能指出我正确的方向?

(如果可能的话,我希望它能够在客户端工作)

【问题讨论】:

  • 它必须匹配这 5 个中的 3 个 unique
  • 是的,如果可能的话。它会在所有收到的电子邮件中搜索我概述的单词。如果在任何一封电子邮件中匹配了一定数量的这些单词(例如 50%),我的规则引擎将删除该电子邮件。如果单词树在一封电子邮件中出现 3 次,则它只会返回一个匹配项。如果 tree 出现 3 次, cat 出现 2 次,这将返回两个单词匹配的值,但仍会导致不匹配。

标签: java regex expression


【解决方案1】:

它必须是一个独立的正则表达式,没有任何进一步的代码吗?对每个单词和计数匹配进行简单的循环测试应该可以完美地做到这一点。伪代码假设您想要 N 个唯一匹配项(您也可以将子字符串测试与正则表达式交换,只要您将唯一匹配项的计数排除在正则表达式之外,无论您如何确定匹配项):

bool has_N_words(int n, string[] words, string text) {
    int matches = 0;
    foreach word in words {
        if (word.substringOf(text)) counter++
        if (counter >= n) return true
    }
    return false
}

在我看来,这是唯一(保存令人兴奋的晦涩正则表达式扩展的使用 - 并不是我有什么想法,我只是一次又一次地对现代正则表达式实现所允许的内容感到惊讶)使用常规方法来做到这一点表达式是这样的:

  1. 枚举单词的所有唯一(忽略顺序或不取决于实现,见下文)排列
  2. 对于每个排列,构建一个与包含这些单词的字符串匹配的子正则表达式,或者通过
    1. .*? 连接前三个单词(这需要所有唯一的排列)
    2. 使用三个前瞻断言,如 (?=.*word)(这允许以不同的顺序删除之前出现的单词组合)
  3. 将所有子正则表达式组合成一个巨型或。

手动完成是不切实际的,自动完成既丑陋又复杂(如计算复杂性,而不是编程工作),效率低下,而且无论哪种方式都非常笨拙。

【讨论】:

  • 非常感谢您的回复!我相信它一定是一个独立的正则表达式。虽然我使用的引擎在正则表达式上运行并且是服务器端,但似乎所需的代码只是客户端。我尝试使用类似于 [cat?|dog?|tree?]{1,3} 的东西,但没有成功。
  • @confused:好吧,如果它必须是一个单独的正则表达式,我担心它必须像我在答案的第二部分中描述的那样,即枚举所有可能的组合。
【解决方案2】:

我不明白您为什么要使用正则表达式来执行此操作,但如果您真的需要它成为正则表达式:

/(树|汽车|狗|猫|鸟)/

然后计算你从中得到的匹配项......

【讨论】:

  • 请注意,这仅适用于每个单词有多个匹配项。
  • 正则表达式被用于过滤系统中不需要的电子邮件。因此,它会自动禁止任何提及 5 个(出于论证原因)术语中的 3 个的电子邮件。计算比赛是行不通的。 /(tree|car|dog|cat|bird)/ 它会搜索这些术语,而我的代码会自动删除这些电子邮件。但是,只有在 5 个术语中至少有 3 个匹配时。可以是三个、四个或所有单词,但不能是 2 个或一个。
【解决方案3】:
(?i)(?s)(.*(tree|car|dog|cat|bird)){3,}?.*

(?i) 用于不区分大小写,(?s) 用于匹配带有 .* 的新行,因为您正在查看电子邮件。
这 ?最后是勉强的量词。

我还没有真正尝试过。

【讨论】:

    猜你喜欢
    • 2015-02-23
    • 2018-01-17
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2014-06-02
    • 2023-04-10
    • 2013-08-16
    • 1970-01-01
    相关资源
    最近更新 更多