使用正则表达式和scala匹配域名

时间:2013-05-16 09:50:15

标签: regex scala

我尝试过这个问题的正则表达式:how to get domain name from URL

但是找不到域名。这是我的实施:

    val Names = """.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$""".r
    val s = Names.findFirstIn("www.google.com")
    s match {
    case Some(name) =>
        println(name)
    case None =>
        println("No name value")
    }

“没有名称值”一直打印到std out。正则表达式或我的Scala实现是否存在问题?

3 个答案:

答案 0 :(得分:2)

我通过在扩展名前添加.来修复正则表达式。顺便说一句,既然你必须得到你感兴趣的小组(#1),你应该使用findFirstMatchIn而不是findFirstIn

val Names = """([^.]+)\.(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$""".r
val s = Names.findFirstMatchIn("www.google.com")
s match {
case Some(name) =>
  println(name)
  println(name.group(1))
case None =>
    println("No name value")
}

打印:

google.com
google
Names: scala.util.matching.Regex = ([^.]+)\.(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$
s: Option[scala.util.matching.Regex.Match] = Some(google.com)

编辑:抱歉,我误解了你的问题。我重写了答案。

答案 1 :(得分:2)

我会使用Scalas 2.10字符串插值功能:

implicit class Regex(sc: StringContext) {
  def r = new util.matching.Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
}

scala> "www.google.co.uk" match {
      case  r"(.*?)$sld([^.]+)$domain\.(com|net|org|co\.uk)$tld" => (sld,domain,tld)
      case _ => ???
    }
res61: (String, String, String) = (www,google,co.uk)

这种方法的问题在于您始终需要使用变量捕获每个组。要禁用此功能,您需要显式添加非捕获组(以?:开头):

r".*?([^.]+)$domain\.(?:com|net|org|co\.uk)"

对于第一组,也可以完全不用它。

如果您确定可以始终匹配输入字符串,也可以省略模式匹配的不匹配部分:

scala> val r".*?([^.]+)$domain\.(?:com|net|org|co\.uk)" = "www.google.com"
domain: String = google

答案 2 :(得分:1)

scala> val Names = """.*?([^\.]+)\.(?:com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)""".r
Names: scala.util.matching.Regex = .*?([^\.]+)\.(?:com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)

scala> val Names( primary ) = "www.google.com"
primary: String = google

变更:

  • 注意?在最初的。* - 贪婪的匹配可以匹配到e.com,所以关闭它!
  • 添加'。'在你想要的组和(com | net ...)部分之间。你希望dot是一个边界
  • 你不希望(com | net ...)部分定义一个捕获组,所以使用(?:...)而不仅仅是(...)
  • 我最后删除了$。这可能是无偿的。
祝你好运!