2014-12-26 46 views
5

我想寫一個正則表達式來匹配這些URL中的數字(123456781234567890)。如何編寫正則表達式從這些URL中提取數字?

http://www.example.com/p/12345678 
http://www.example.com/p/12345678?foo=bar 
http://www.example.com/p/some-text-123/1234567890?foo=bar 

規則:

  • 數字斜線後總是
  • 的數字可以長短不一
  • 正則表達式必須檢查的網址有/p/在他們
  • 號碼可能在URL的末尾,或者可能在其後面有變量

我嘗試:

\/p\/([0-9]+) 

,第一和第二,而第三個相匹配。所以我嘗試過:

\/p\/[^\/?]*\/?([0-9]+) 

沒有快樂。

REGEX 101

+2

你打算在要使用該什麼正則表達式引擎(什麼編程語言?) –

+0

「\/[^ \ d]」?或甚至只是「[^ \ d]」或「[^ \ d +]」會做我相信的詭計嗎? – Adam

+0

@MichaelBerkowski PHP – Nate

回答

2

正則表達式可能不適合這個工作的工具。看起來在任何情況下,使用URL解析器分割URL都會更有意義。在您的示例中,數字部分似乎總是URL的路徑部分中的最後一項。我不確定你使用的是什麼語言,但許多語言提供的功能可以將URL解析爲其組成部分。

$path = parse_url($url, PHP_URL_PATH); 
if(strpos($path, "/p/") === 0) { 
    $base = basename($path); 
} else { 
    // error 
} 

每次都有效,假設$ url是您正在解析的字符串。

+0

以刪除對'parse_url'的多餘調用。可以將'$ path'傳遞給基本名稱,而不是再次調用'parse_url'。 – superultranova

1

我伸出你的版本,現在適用於所有的例子:

\/p\/(.+\/)*(\d+)(\?.+=.+(&.+=.+)*)?$ 

如果你不關心的URL是有效的,可以收縮的正則表達式:

\/p\/(.+\/)*(\d+)($|\?) 

https://regex101.com/r/pW5qB3/2

+0

最後所有的東西都不是必須的,因爲這只是'/ p /'和'\ d +'這個問題。 –

+1

@MichaelBerkowski,但OP提到數字應該是網址的最後一部分,只有參數可能會跟隨,所以這確保網址是有效的,只有參數來自數字 – msrd0

+0

事實的確如此。你可以用'($ | \?)'來跟着它,這樣下一個查詢字符串或字符串的末尾就會出現。沒有必要表達'key = value&key = value' –

-2
var regex = new Regex(@"/(?<ticket>\d+)"); 

var subject = "http://www.example.com/p/some-text-123/1234567890?foo=bar"; 

var ticket = regex.Match(subject).Groups["ticket"].Value; 

輸出:1234567890

+2

這將匹配不包含'/ p /'的URL,這是必需的。 –

0

如果我沒有理解好了,你想只能是數字:

  • 之後URL的最後一個斜線
  • 不能是變量的一部分,即/p/123?foo=bar456比賽123
    /p/foobar?foo=bar456匹配什麼

然後,您可以使用下面的正則表達式:

(?=/p/).*/\K\d+ 

說明

(?=/p/) # lookahead: check '/p/' is in the URL 
.*/  # go to the last '/' thanks to greediness 
\K  # leave everything we have so far out of the final match 
\d+  # select the digits just after the last '/' 

爲了避免逃避斜線沒有使用這些爲regex delimiters#(?=/p/).*/\K\d+#會做得很好。

請參閱demo here

0
\/p\/(?:.*\/)?(\d+)\b 

您可以嘗試this.This將捕獲根據您coditons.See整數demo.Grab捕獲或組。

https://regex101.com/r/dU7oN5/29

$re = "/\\/p\\/(?:.*\\/)?(\\d+)\\b/"; 
$str = "http://www.example.com/p/12345678\nhttp://www.example.com/p/12345678?foo=bar\nhttp://www.example.com/p/some-text-123/1234567890?foo=bar"; 

preg_match_all($re, $str, $matches);