2012-09-16 37 views
0

可能重複:
Regex/Preg: No match, if found匹配文本,如果它不包含某些子

我想用preg_replace替換一些字符串,如果事情在字符串中是不存在的。也就是說,如果子字符串在那裏,字符串將不匹配。

例如,如果字符串包含.png,它將不會找到/匹配它。

example.com/image.png 

這裏,因爲字符串包含行/子.png它不會找到它。

example.com/image 

這裏,會發現它,因爲這個串包含行/子.png任何地方。


對於那些仍然沒有得到我的人。

$result = preg_replace("#http://(.*\S)[Something here that will not match the link if it finds the .png at last]#","<a href='\\1'>\\1</a>","Here is a link that should work http://example.com/; Here is a link that should NOT work http://example.com/image.png") 
+1

是'example.com/image'整個字符串,或者只是字符串的一部分?如果它只是字符串的一部分......找到它的標準是什麼? – 2012-09-16 15:19:49

+0

喜歡,如果它是一個帖子:「你好,看看這個!http://example.com/image」它會找到鏈接,並使其與preg_replace鏈接,但如果它是這樣的:「你好,檢查這out!http://example.com/image.png「它只是不會做任何事情...... – do0l67

+0

所以你想匹配的網址?你已經有了一個正式的表達方式嗎? – 2012-09-16 15:22:19

回答

1

好的,我在這裏出去。

首先,你需要一個正則表達式來爲你找到一個URL。既然你顯然希望找到大量無效的網址,我們也將採取簡單地認爲包含序列<letter>.<letter>連續的非空格字符的任意字符串正則表達式:

\b(?=\S*[a-z]\.[a-z])\S+(?=\s|$) 

然後我們可以檢查這個序列在.png並沒有結束:

\b(?=\S*[a-z]\.[a-z])\S+(?=\s|$)(?<!\.png) 

現在,你可以利用它來進行替換操作,例如

$result = preg_replace(
    '/\b   # Start at a word boundary 
    (?=   # Assert that it\'s possible to match... 
    \S*   # any number of non-whitespace characters 
    [a-z]\.[a-z] # followed by an ASCII letter, a dot, a letter 
    )    # End of lookahead assertion 
    \S+   # Match one or more non-whitespace characters 
    (?=\s|$)  # until the next whitespace or end of string 
    (?<!\.png)  # unless that match ends in .png/ix', 
    '<a href="\0">\0</a>', $subject); 
+0

+1很好的正則表達式:) – Pebbl

+0

那麼,出於某種原因,它不會與?<!要麼 ?! – do0l67

+0

我已經測試了我的本地版本的PHP 5.3.6,它似乎適用於我...您使用了哪個版本(內聯或帶註釋的版本)? 'preg_replace('#\ b(?= \ S * [az] \。[az])\ S +(?= \ s | $)(?<!\。png)#i','\0',$ text );'正在爲我工​​作... – Pebbl

0

這將是我將如何解決這個問題,獲得「不」RegExp工作非常棘手 - 因爲它不是真正的系統設計。因此,而不是單獨的邏輯,以便您有兩個正則表達式的...一個搜索鏈接狀結構,然後一個給你希望避免的情況下檢查:

function replaceWithLink ($find) { 
    list($link) = $find; 
    if (preg_match('/\.(png|gif|image)$/', $link)) { 
    return $link; 
    } 
    else { 
    return '<a href="'.$link.'">'.$link.'</a>'; 
    } 
} 

$text = 'This is my test string that contains a url.like/thing but '. 
     'it also contains another url.like/thing/that-has-an.image '. 
     'should they all be highlighted?'; 

$expr = '#[a-z0-9:_\-\.]+/[a-z0-9_\-\./]+#i'; 
$func = 'replaceWithLink'; 

$text = preg_replace_callback($expr, $func, $text); 

以上是比擁有一個更具可讀性過於複雜的RegExp,並且易於擴展以處理更多擴展。顯然,爲了使這個網址正確工作,您可能需要調整正在搜索它們的RegExp - 我只是相當快地將它們放在一起。在我的版本中,URL必須包含URL-like text,然後是/,然後是URL-like text possibly with slash才能符合條件。

0

如何這一點:

$yourInputString = 'whatever'; 
$matchPattern = '/^.*?(?<!\.png)$/i'; 
$replacePattern = '$0.png'; 
$result = preg_replace($matchPattern, $replacePattern, $yourInputString); 

請注意,您輸入的字符串會需要只包含你正在處理的鏈接,例如:

example.com/image.png 

example.com/image 

下面是模式的解釋:

# ^.*?(?<!\.png)$ 
# 
# Options: case insensitive 
# 
# Assert position at the beginning of a line (at beginning of the string or after a line break character) «^» 
# 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 it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<!\.png)» 
# Match the character 「.」 literally «\.» 
# Match the characters 「png」 literally «png» 
# Assert position at the end of a line (at the end of the string or before a line break character) «$» 
相關問題