2012-09-07 38 views
0

我有一個url grabber設置,它工作正常。它抓住了一個文檔是在響應頭如的網址:PHP正則表達式查找字符串,直到

<script type='text/javascript' language='JavaScript'> 
document.location.href = 'http\x3a\x2f\x2fcms.example.com\x2fd\x2fd\x2fworkspace\x2fSpacesStore\x2f61d96949-b8fb-43f1-adaf-0233368984e0\x2fFinancial\x2520Agility\x2520Report.pdf\x3fguest\x3dtrue' 
</script> 

這是我的採集腳本。

<?php 

set_time_limit(0); 
$target_url = $_POST['to']; 
$html =file_get_contents($target_url); 

$pattern = "/document.location.href = '([^']*)'/"; 
preg_match($pattern, $html, $matches, PREG_OFFSET_CAPTURE, 3); 

$raw_url = $matches[1][0]; 
$eval_url = '$url = "'.$raw_url.'";'; 

eval($eval_url); 
echo $url; 

我們有一個變量添加到我們的文檔管理系統,使每個文檔的網址需要?來賓=真正的網址的結尾。當我們這樣做時,我的抓取器返回完整的URL並將其附加到文件名。所以我試圖讓它抓取url直到它碰到/ guest = true。使用此代碼:

<?php 

set_time_limit(0); 

$target_url = $_POST['to']; 
$html =file_get_contents($target_url); 

$pattern = "/document.location.href = '([^']*)\x3fguest\x3dtrue'/"; 

preg_match($pattern, $html, $matches, PREG_OFFSET_CAPTURE, 3); 

$raw_url = $matches[1][0]; 
$eval_url = '$url = "'.$raw_url.'";'; 

eval($eval_url); 
echo $url; 

爲什麼它不會返回url直到?guest = true部分?又如何不工作?和什麼是修復?

+0

當原始字符串包含'\ x3f'和'\ x3d'時,爲什麼要匹配'?'和'='?將後者變成前者是預期的。 – raina77ow

+0

@ raina77ow是的,我嘗試完全匹配,這個副本和粘貼來自一個挫折嘗試。兩者都不能運作 – McPace

回答

1

這是解決方案。你會直接得到比賽,而不是小組。

set_time_limit(0); 

$target_url = $_POST['to']; 
$html = file_get_contents($target_url); 

$pattern = '/(?<=document\.location\.href = \').*?(?=\\\\x3fguest\\\\x3dtrue)/'; 

preg_match($pattern, $html, $matches)) 

$raw_url = $matches[0]; 
$eval_url = '$url = "'.$raw_url.'";'; 

eval($eval_url); 
echo $url; 

您可以檢查出來的結果here

你的正則表達式的問題在於,你沒有逃避字符串中的某些字符(.\),你想要捕捉文學作品。此外,您不需要使用PREG_OFFSET_CAPTURE3的補償。我想你從this page的例子中複製了這些值。

這裏的正則表達式的解釋:

# (?<=document\.location\.href = ').*?(?=\\x3fguest\\x3dtrue) 
# 
# Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=document\.location\.href = ')» 
# Match the characters 「document」 literally «document» 
# Match the character 「.」 literally «\.» 
# Match the characters 「location」 literally «location» 
# Match the character 「.」 literally «\.» 
# Match the characters 「href = '」 literally «href = '» 
# Match any single character that is not a line break character «.*?» 
# Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?» 
# Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\\x3fguest\\x3dtrue')» 
# Match the character 「\」 literally «\\» 
# Match the characters 「x3fguest」 literally «x3fguest» 
# Match the character 「\」 literally «\\» 
# Match the characters 「x3dtrue」 literally «x3dtrue» 

這個答案已被編輯,以反映更新的問題。

+0

謝謝尼古拉,我粘貼了錯誤的代碼,並試圖匹配\ x3fguest \ x3dtrue not?guest = true。在你的代碼中使用它並沒有給我我正在尋找的結果 – McPace

+0

@McPace我已經更新了答案,請讓我知道它現在是否適用於你。 –

+0

你搖滾!並感謝您的解釋。 – McPace

0

看來你的正則表達式是錯誤的。您將\?guest=true添加到您的正則表達式中,字面上匹配?guest=true

在您的示例響應標題中,它以\x3fguest\x3dtrue結尾,這是不同的。

嘗試:

$pattern="/document.location.href = '([^']*)(\?|(\\x3f))guest(=|(\\x3d))true'/"; 

我只是取代了下面的子表達式:現在

  • \?(\?|(\\x3f))相匹配?\x3f字面上
  • =現在是(=|(\\x3d))相匹配=\x3d字面上

這樣,如果使用轉義的十六進制表示?=,它仍然會正確匹配。

+0

謝謝ronalchn,這看起來好像會起作用,但事實並非如此。這會改變我的比賽結果是否正確?我需要使用比賽[1] [0]以外的東西嗎? – McPace