匹配文本,如果它不包含某个子字符串

时间:2012-09-16 15:18:14

标签: php regex preg-replace

  

可能重复:
  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")

3 个答案:

答案 0 :(得分:1)

好的,我今天出去了。

首先,您需要一个能为您找到URL的正则表达式。由于您显然也希望找到大量无效的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);

答案 1 :(得分:0)

这就是我如何处理这个问题,让“不”RegExp工作起来相当棘手 - 因为它并不是系统的设计目的。因此,请将逻辑分开,以便您有两个RegExps ...一个搜索类似链接的结构,然后检查一个您想要避免的案例:

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更具可读性,并且可以轻松扩展以处理更多扩展。显然,为了使URL能够正常工作,您可能需要调整正在搜索它们的RegExp - 我只是很快就把它们抛在了一起。在我的版本中,网址必须包含URL-like text,然后是/,后跟URL-like text possibly with slash才能获得资格。

答案 2 :(得分: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) «$»