2013-02-13 82 views
0

問題:作者在CMS中錯誤地添加了電子郵件地址 - 錯過了「mailto:」文本。正則表達式替換損壞的電子郵件鏈接

我需要一個正則表達式,如果可能的話,在存儲的MySQL內容表上進行搜索和替換。

情況下,我需要應付有:

  1. 沒有 '至mailto:'
  2. '的mailto:' 已經包括(正確)
  3. 網頁地址不是電子郵件 - 沒有更換
  4. 多個mailto:必需(多個字符串中的一個)

示例字符串爲:(爲了便於閱讀,添加了換行符)

<a href="[email protected]">[email protected]</a> and 
<a href="mailto:[email protected]">[email protected]</a> and 
<a href="http://www.test.com/">real web link</a> 
second one to replace <a href="[email protected]">[email protected]</a> 

需要的輸出將是:

<a href="mailto:[email protected]">[email protected]</a> and 
<a href="mailto:[email protected]">[email protected]</a> and 
<a href="http://www.test.com/">real web link</a> 
second one to replace <a href="mailto:[email protected]">[email protected]</a> 

我想(在PHP)什麼和問題:

pattern: /href="(.+?)(@)(.+?)(<\/a>)/iU 
replacement: href="mailto:$1$2$3$4 

這是增加至mailto:在格式正確的mailto:貪婪地行事在最後兩個鏈接。

感謝您的任何幫助。我看了一下,但因爲這是一個意外的內容問題,所以我沒有時間。

如果你能節省時間並給出SQL表達式,那會更好。

+0

MySQL沒有REGEXP頂替內置有用戶定義的函數,但它看起來像一個轉儲隨後離線處理是最好的選擇 - 看: [堆棧溢出討論如何做-DO-A-正則表達式替換合的MySQL](http://stackoverflow.com/questions/986826/how-to-do-a-regular-expression-replace-in-mysql) – mjpg 2013-02-13 13:38:40

回答

1

嘗試更換

/href="(?!(mailto:|http:\/\/|www\.))/iU 

href="mailto: 

?!鬆散的意思是 「下一個字符不是這些。」

備選:

替換

/(href=")(?!mailto:)([^"][email protected])/iU 

$1mailto:$2 

[^"]+裝置1個或多個字符不屬於"

你可能需要保證正確性更復雜的匹配模式。

MySQL的正則表達式匹配:

thisthis

+0

第一個在PHP中運行正常但需要轉義: '/ href =「(?!(mailto:| http:\/\/| www \。))/ iU';' – mjpg 2013-02-13 13:27:40

+0

第二個給出重複的地方mailto已經存在了: 'mailto:mailto:' 非常感謝這個 - 我會先嚐試SQL – mjpg 2013-02-13 13:29:31

+0

@mjpg修正它們 – Dukeling 2013-02-13 13:34:28

0

使用以下作爲圖案:

/(href=")(?!mailto:)([email protected]+?")/iU 

並用

$1mailto:$2 

(?!mailto:)替換它是負先行檢查是否mailto:如下。如果沒有這樣的一個,則檢查剩餘部分是否匹配。 ([email protected]+?")匹配一個或多個字符後跟一個@後跟一個或多個字符後跟一個"+都是非貪婪的。

將匹配的圖案替換爲第一捕獲組(href="),接着是mailto:,隨後是第二捕獲組(最多關閉")。

+0

感謝這個。 它似乎沒有工作的第二封電子郵件鏈接沒有mailto: – mjpg 2013-02-13 13:31:35

+0

@mjpg在這種情況下,它不工作?就我的測試而言,它似乎正在爲您的例子工作。 – 2013-02-13 14:05:33

+0

對於我的安裝,它不會代替 ''href =「[email protected]」' – mjpg 2013-02-13 14:55:15

1

您需要先申請一個正確的郵件模式:(:(mailto:|) e.g),與去年preg_replace_callback適合這個(例如Using a regular expression to validate an email address),郵件或沒有之前mailto:秒搜索。

這看起來像你的願望(在雙引號僅搜索電子郵件地址)工作;

$s = '<a href="[email protected]">[email protected]</a> and 
<a href="mailto:[email protected]">[email protected]</a> and 
<a href="http://www.test.com/">real web link</a> 
second one to replace <a href="[email protected]">[email protected]</a>'; 
echo preg_replace_callback(
    '~"(mailto:|)([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4}))"~i', 
    function($m) { 
     // print_r($m); @debug 
     return '"mailto:'. $m[2] .'"'; 
    }, 
    $s 
); 

根據需要輸出; 。

 
<a href="mailto:[email protected]">[email protected]</a> and 
<a href="mailto:[email protected]">[email protected]</a> and 
<a href="http://www.test.com/">real web link</a> 
second one to replace <a href="mailto:[email protected]">[email protected]</a> 
+0

非常感謝。這工作對我的測試,除了我有PHP 5.2,所以我不得不使用一個正常的功能: ' 函數cbfunc($ m){ \t回''mailto:'。 $ M [2] '「'; } \t $ =中newstr preg_replace_callback( \t」〜「(的mailto:。。|)([_ A-Z0-9 - ] +(\ [_ A-z0-9- ] +)* @ [A-Z0-9 - ] +(\ [A-Z0-9 - 。] +)*(\。[A-Z] {2,4-}))「〜I」, \t cbfunc, \t $ S \t); ' 但是我需要SQL,所以preg_replace_callback()不可用。 – mjpg 2013-02-13 13:18:10