我正在使用scala regex从URL中提取令牌
我的网址是http://www.google.com?x=10&id=x10_23&y=2 在这里我想在id前面提取x10的值。请注意_23是可选的,可能会也可能不会出现,但如果出现,则必须将其删除。
我写的正则表达式是
val regex = "^.*id=(.*)(\\_\\d+)?.*$".r
x match {
case regex(id) => print(id)
case _ => print("none")
}
这应该有效,因为(\\_\\d+)?
应该使_23成为一个整体。
所以我不明白它为什么不打印。
答案 0 :(得分:1)
请注意,由于第一个贪婪点匹配子模式,您的模式^.*id=(.*)(\\_\\d+)?.*$
实际上将x10_23&y=2
放入组1中。由于(_\d+)?
是可选的,因此第一个贪婪子模式不必为该捕获组生成任何字符。
您可以使用
val regex = "(?s).*[?&]id=([^\\W&]+?)(?:_\\d+)?(?:&.*)?".r
val x = "http://www.google.com?x=10&id=x10_23&y=2"
x match {
case regex(id) => print(id)
case _ => print("none")
}
请注意,不需要定义^
和$
- 默认情况下,该模式会锚定在Scala中。 (?s)
确保我们匹配完整的输入字符串,即使它包含换行符号。
答案 1 :(得分:1)
另一个想法是使用内置的URI Java类及其getQuery()
方法,而不是使用正则表达式来提取令牌。在那里,您可以按=
拆分查询,然后检查其中一个是否以id=
开头并提取值。
例如(仅作为示例):
val x = "http://www.google.com?x=10&id=x10_23&y=2"
val uri = new URI(x)
uri.getQuery.split('&').find(_.startsWith("id=")) match {
case Some(param) => println(param.split('=')(1).replace("_23", ""))
case None => println("None")
}
我发现维护正则表达式更简单,但这只是我的想法!