已经给了我两个列表,我需要检查站点列表中是否有任何项目位于被忽略的站点中。当我运行下面的代码时,它只会打印出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}") : ""
}
答案 0 :(得分:2)
首先,您要在数组中混合正则表达式和字符串。我建议您将它们放在单独的列表中。 第二,要注意时髦的斜线弦。
我修改了您的代码,以使您看到slashy strings(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
由于斜线,被常规用法解释为字符串。 另一方面
groo{2}vy-lang\.org == class java.util.regex.Pattern
是一个正则表达式,但是其中的{2}
表示o正好出现2次。
简而言之,groo{2}vy-lang\.org
将与grooovy-lang.org
相匹配(请注意其中的三个o)。
答案 1 :(得分:2)
以网站为模式,但假设这就是您的意思,这是非常不寻常的:
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" }
答案 2 :(得分:1)
实际上,我不同意已接受的答案,这似乎是面试官希望您陷入的陷阱。
要对此进行检查,您可以将~/groo{2}vy-lang\.org/
更改为~/gro{2}vy-lang\.org/
,然后亲自查看"groovy-lang.org"
仍然会被忽略。
这是因为java.util.Collection.contains()
并没有变得聪明(可能是因为它没有被Groovy覆盖),并且在这种特殊情况下只是检查是否相等(定义为here)。
因此"groovy-lang.org" ==~ /gro{2}vy-lang.org/
(模式匹配)但是"groovy-lang.org" != ~/gro{2}vy-lang.org/
(它们不是相等的对象,而groovy truth没有抽象出该特定情况)。
“忽略”测试基于对象相等性,而不是基于模式匹配,因为访问员可能会自愿误导您相信。
希望这会有所帮助,而且我没有记错。