Regex Groovy:如何检查一个列表是否包含来自另一个包含正则表达式格式的列表的项

Regex Groovy:如何检查一个列表是否包含来自另一个包含正则表达式格式的列表的项,regex,list,groovy,Regex,List,Groovy,我得到了两个列表,我需要检查站点列表中的任何项目是否在ignoredSites中。当我运行下面的代码时,它只打印出google.co.uk,但是,它不应该也打印出amazon.co.uk和groovy-lang.org吗 有人能解释一下为什么没有 def ignoredSites = ["www.amazon.com", /amazon.co.*/, /www.scala-lang.org/,/google.co.uk/, ~/htt(p|ps):\/\/www\.amazon\.co.*/,

我得到了两个列表,我需要检查站点列表中的任何项目是否在ignoredSites中。当我运行下面的代码时,它只打印出google.co.uk,但是,它不应该也打印出amazon.co.uk和groovy-lang.org吗

有人能解释一下为什么没有

def ignoredSites = ["www.amazon.com", /amazon.co.*/, /www.scala-lang.org/,/google.co.uk/, ~/htt(p|ps):\/\/www\.amazon\.co.*/, "groovy-lang.org"]
def sites = ["amazon.co.uk", ~/groo{2}vy-lang\.org/, "google.co.uk", "amazon.com", ~/scala.*/]


sites.each { site ->
    ignoredSites.contains(site) ? println("Ignored: ${site}") : ""
}

首先,在数组中混合正则表达式和字符串。我建议你把它们列在单独的清单上。 其次,请注意groovy slashy字符串

我修改您的代码是为了让您看到(amazon.co.*、www.scala-lang.org、google.co.uk)实际上被解释为字符串,而不是预期的正则表达式

在您的情况下,因为您在数组中混合了正则表达式和字符串,所以必须以不同的方式进行检查:

def ignoredSites = ["www.amazon.com", /amazon.co.*/, /www.scala-lang.org/,/google.co.uk/, ~/htt(p|ps):\/\/www\.amazon\.co.*/, "groovy-lang.org"]
def sites = ["amazon.co.uk", ~/groo{2}vy-lang\.org/, "google.co.uk", "amazon.com", ~/scala.*/]


println '==========sites============'
sites.each { site ->
  println site.toString() + " == "+ site.class
}
println '==========ignoredSites============'
ignoredSites.each { site ->
  println site.toString() + " == "+ site.class
}
println '======================'

sites.each { site ->
     if(site.class.equals(java.util.regex.Pattern)){
       ignoredSites.each{ is ->
         if(is.class.equals(java.lang.String)){
           if(is.matches(site)) println("Ignored: ${site}") //string = regex
         } else {
           //can't match 2 regex
         }
       }
     } else {
       ignoredSites.each{ is ->
         if(is.class.equals(java.lang.String)){
           if(is.equals(site)) println("Ignored: ${site}") //string = regex
         } else {
           if(site.matches(is)) println("Ignored3: ${site}") //string = regex
         }
       }
     }
}
已编辑

如果使用打印元素类型运行代码,您将注意到以下事项:

==========sites============
amazon.co.uk == class java.lang.String
groo{2}vy-lang\.org == class java.util.regex.Pattern
google.co.uk == class java.lang.String
amazon.com == class java.lang.String
scala.* == class java.util.regex.Pattern
==========ignoredSites============
www.amazon.com == class java.lang.String
amazon.co.* == class java.lang.String
www.scala-lang.org == class java.lang.String
google.co.uk == class java.lang.String
htt(p|ps)://www\.amazon\.co.* == class java.util.regex.Pattern
groovy-lang.org == class java.lang.String
======================
因此,amazon.co.uk不匹配,因为应该匹配它的正则表达式:

amazon.co.* == class java.lang.String
由于slashy字符串,groovy将其解释为字符串。 另一方面

groo{2}vy-lang\.org == class java.util.regex.Pattern
是一个正则表达式,但其中的
{2}
表示o正好出现2次。
简而言之,
grooovy-lang\.org
将匹配
grooovy-lang.org
(注意其中的三个o)。

将站点作为一种模式是相当不寻常的,但假设这就是您的意思:

def ignoredSites = ["www.amazon.com", /amazon.co.*/, /www.scala-lang.org/,/google.co.uk/, ~/htt(p|ps):\/\/www\.amazon\.co.*/, "groovy-lang.org"]
def sites = ["amazon.co.uk", ~/gro{2}vy-lang\.org/, "google.co.uk", "amazon.com", ~/scala.*/]

sites.findAll { site ->
    ignoredSites.find{ it == site || (site in String && site.matches(it) || (it in String && it.matches(site))) }
}.each{ println "Ignored: $it" }

事实上,我不同意被接受的答案,这看起来像是面试官希望你落入的陷阱

要检查这一点,您只需将
~/groo{2}vy lang\.org/
更改为
~/groo{2}vy lang\.org/
,并亲自看到
“groovy-lang.org”
仍然不会被忽略

这是因为
java.util.Collection.contains()
并不想变得聪明(可能是因为它没有被Groovy覆盖),在这种特殊情况下,它只是检查等式(如定义的)

所以
“groovy-lang.org”==~/gro{2}vy-lang.org/
(模式匹配),但是
“groovy-lang.org”!=~/gro{2}vy-lang.org/
(它们不是相等的对象,也不会抽象出特定的情况)

“忽略”测试基于对象平等性,而不是模式匹配,因为面试官可能会自动误导你相信


希望这能有所帮助,我没有弄错。

谢谢您的反馈,但我不会更改代码,因为这是求职面试技术测试的一部分。他们提出的问题是解释为什么站点中的每个元素都会/不会出现在ignoredSites中。我试图理解为什么amazon.co.uk和groovy-lang.org在我执行代码时不显示。