2011-05-02 34 views
2

我試圖自己解決這個問題(甚至買了一本Kindle電子書!),但我正在努力解決php中的反向引用問題。rexexp for php的解決方案

我要的是像下面的例子:

var $html = "hello %world|/worldlink/% again"; 

output: 
hello <a href="/worldlink/">world</a> again 

我嘗試這樣的東西:

preg_replace('/%([a-z]+)|([a-z]+)%/', '<a href="\2">\1</a>', $html); 

,但沒有喜悅。

有什麼想法嗎?我相信有人會發布確切的答案,但我也想請一個解釋 - 以便我不必再問這些問題:)

+0

定義 「無歡」。你做了什麼_exactly_,結果是什麼_exactly_? – 2011-05-02 17:27:29

+1

我整理了一下你的問題。請花點時間去做一些小事,比如把'i's變成大寫字母;對於那些花時間回答你的問題的人來說,這只是一個小小的禮貌。我還注意到,對於21個問題中的大部分問題都有良好的解決方案,但您只接受25%的答案。 – 2011-05-02 17:39:04

+0

關於您的第一條評論,我錯誤地認爲任何經驗豐富的正則表達式專家都可以嘗試自己嘗試。對不起,如果我錯誤地假設。關於你的第二條評論,我實際上對你的「糾正」態度感到不滿。如果我親自與俚語交談,你會糾正我嗎?此外,我看了一下其他問題,並禁止那些奇怪的問題,但實際的答案並不奏效 - 其中一些我實際上提到並要求提供更多幫助。我的問題很清晰,有禮貌,但爲了您的利益,我已經在皇后英語中寫下了這個問題。 – khany 2011-05-02 19:23:37

回答

0

下面是根據提供(使用非斜線分隔符,以避免逃逸斜線)的OP的數據/信息工作的版本:使用非斜線定界符

preg_replace('#%([a-z]+)\|([a-z/]+)%#', '<a href="\2">\1</a>', $html); 

,將減輕需要逃避斜線。

輸出:

hello <a href="/worldlink/">world</a> again 

闡釋

爲什麼你沒有工作。首先,|是一個OR運算符,並且在您的示例中應該轉義。其次,由於您使用的是/或預計會出現斜槓,因此最好使用非斜槓分隔符,如#。第三,斜線需要被添加到允許的匹配列表中。如前所述,您可能希望包含更多選項,因爲任何類型的帶數字的單詞都會強調句點連字符會失敗/中斷腳本。希望這是你正在尋找的解釋。

+0

這僅對所有URL的_very_嚴格子集「完全正確」。 – 2011-05-02 17:33:10

+0

修改了第一行以安撫挑剔的人。 @Tomalak,從技術上講,事實上並非如此。但就主要文章中給出的例子和期望的結果而言,這是一個完全正確的版本。 OP沒有聲明他需要擴大範圍,如果他的答案會是不同的。 – 2011-05-02 17:35:14

+0

@BradFJacobs:我想,這很清楚他想要做什麼,那就是鏈接網址。我的回答並沒有爲他提供完整的解決方案,但它指出'([a-z /] +)'幾乎不是URL匹配捕獲;我想你的回答會更好,如果這樣做的話。 – 2011-05-02 17:37:35

1

斜線「/」不包括在您允許的範圍內[a-z] 。而是使用

preg_replace('/%([a-z]+)\|([a-z\/]+)%/', '<a href="\2">\1</a>', $html); 
+1

您還需要轉義'|'和'/'。 – mellamokb 2011-05-02 17:26:08

+0

或者使用不同的分隔符,那麼/會很好。 (如'#') – 2011-05-02 17:26:48

+0

並且可能希望擴大搜索範圍,以防用戶在路上稍後有類似「Page.HTML」的鏈接。 – mellamokb 2011-05-02 17:27:53

1

你的表達:

'/%([a-z]+)|([a-z]+)%/' 

只捕獲一兩件事。中間的|表示「或」。你試圖捕獲兩者,所以你在那裏不需要OR。你想要一個literal |符號所以你要逃避它:

'/%([a-z]+)\|([a-z\/]+)%/' 

/角色也需要納入你的字符集,如上面逃脫。

+1

請原諒我的無知,這是什麼RHS? – Erik 2011-05-02 17:31:23

+0

右側。你[有點]現在修好了。 – 2011-05-02 17:33:43

0

這裏對我來說是什麼在起作用:

preg_replace('/%([a-z]+)\|([a-z\/]+)%/', '<a href="\2">\1</a>', $html); 
+0

是的,這工作謝謝你。並感謝所有在這個問題上的貢獻者。 – khany 2011-05-02 19:37:57

1

您正則表達式(/%([a-z]+)|([a-z]+)%/)讀這樣:

比賽%其次+(=一個或 更多)a-z字符(和存儲此 變成反向引用#1)。

或(所述|):

匹配+(=一個或多個)a-z 字符(和這個存儲到 反向引用#2),接着是 %


你所尋找的是:

preg_replace('~%([a-z]+)[|]([a-z/]+)%~', '<a href="$2">$1</a>', $html); 

基本上我剛剛逃過|regex meta character(您可以通過與[]周圍像我一樣,或只是在前面加上一個向後斜線做到這一點\,我個人認爲前者更易於閱讀),並向第二個捕獲組添加/

我也改變了你的delimiters/~因爲波浪線是更不太可能出現在字符串中,如果你想使用/爲您的分隔符,你也有逃避它們的出現在你的正則表達式來保持。

這也是您使用$語法,而不是\在您更換反向引用recommended

$replacement可能含有或(自PHP 4.0.4) $n引用的形式\\n的 ,後者形式是優選的一個。

+1

我喜歡使用'[|]'。 – 2011-05-02 17:40:12

+0

嗯。謝謝,但我得到這個'world again' so everything exvept the closing '' – khany 2011-05-02 19:34:04

+0

@ khany:我再次'你好world',並且我的正則表達式和你接受的答案沒有什麼大的區別,所以我的猜測是你誤讀了你的結果得到..? – 2011-05-02 22:16:13

0

您的正則表達式不會轉義|,並且不包含URL的正確字符。

這是一個基本live例如僅支持A-Z和斜線:

preg_replace('/%([a-z]+)\|([a-z\/]+)%/', '<a href="\2">\1</a>', $html); 

在現實中,你會想那些[a-z]+塊更改爲更具表現力。做一些URL匹配正則表達式的搜索,並選擇一個適合你想要的。