,你必須是php風格的正則表達式,而不是Java風格的正則表達式 - 例如,請注意0標誌在結尾處。
所以你只需要編輯了一下:
val youtubeRgx = """https?://(?:[0-9a-zA-Z-]+\.)?(?:youtu\.be/|youtube\.com\S*[^\w\-\s])([\w \-]{11})(?=[^\w\-]|$)(?![?=&+%\w]*(?:[\'"][^<>]*>|</a>))[?=&+%\w-]*""".r
我測試了所有可能的YouTube網址,和它的作品。例如:
scala> youtubeRgx.pattern.matcher("http://www.youtube.com/watch?v=XrivBjlv6Mw").matches
res23: Boolean = true
,並提取值:
"http://www.youtube.com/watch?v=XrivBjlv6Mw" match {
case youtubeRgx(a) => Some(a)
case _ => None
}
res33: Option[String] = Some(XrivBjlv6Mw)
這是一個遺憾的是,Java不允許在正則表達式正確的意見,所以我做了我所能做:
val youtubeRgx = """https?:// # Required scheme. Either http or https.
|(?:[0-9a-zA-Z-]+\.)? # Optional subdomain.
|(?: # Group host alternatives.
| youtu\.be/ # Either youtu.be,
|| youtube\.com # or youtube.com followed by
| \S* # Allow anything up to VIDEO_ID,
| [^\w\-\s] # but char before ID is non-ID char.
|) # End host alternatives.
|([\w\-]{11}) # $1: VIDEO_ID is exactly 11 chars.
|(?=[^\w\-]|$) # Assert next char is non-ID or EOS.
|(?! # Assert URL is not pre-linked.
| [?=&+%\w]* # Allow URL (query) remainder.
| (?: # Group pre-linked alternatives.
| [\'"][^<>]*> # Either inside a start tag,
| | </a> # or inside <a> element text contents.
| ) # End recognized pre-linked alts.
|) # End negative lookahead assertion.
|[?=&+%\w-]* # Consume any URL (query) remainder.
|""".stripMargin.replaceAll("\\s*#.*\n", "").replace(" ","").r
(改編from @ ridgerunner的答案在這裏:find all youtube video ids in string)
請不要在Scala中使用'null'。如果視頻ID合法可以或不可以存在,那麼它應該是一個'Option [String]',返回'Some(result)'和'None'。如果正則表達式失敗總是一個硬錯誤,那麼在默認情況下拋出一個異常(或者如果你想對它有很強的功能,可以使用'Either')。 – 2012-07-11 10:55:40
感謝您的提示,你有任何想法,爲什麼正則表達式匹配不會返回結果? – jhdevuk 2012-07-11 11:14:00
不怕;調試既沒有評論也沒有解釋性分解的192字符正則表達式不是我的一杯茶。由於輸出只是一個布爾值(即「不匹配」),解決這個問題的唯一方法是將正則表達式分解成更小的部分,直到找到它失敗的原因爲止 - 這主要是* work *,並且不需要很多知識/見解等等。所以不用謝謝。 – 2012-07-11 12:04:02