如果主题以引号开头,如何不执行preg_replace

时间:2016-05-08 15:42:56

标签: php regex

我尝试使用preg_replace将纯链接转换为HTML链接。但是,它会替换已经转换的链接。

为了解决这个问题,如果链接以引号开头,我希望忽略替换。

我认为可能需要一个积极的前瞻,但我所尝试的一切都没有用。

$string = '<a href="http://www.example.com">test</a> http://www.example.com';

$string = preg_replace("/((https?:\/\/[\w]+[^ \,\"\n\r\t<]*))/is", "<a href=\"$1\">$1</a>", $string);

var_dump($string);

以上输出:

<a href="<a href="http://www.example.com">http://www.example.com</a>">test</a> <a href="http://www.example.com">http://www.example.com</a>

何时输出:

<a href="http://www.example.com">test</a> <a href="http://www.example.com">http://www.example.com</a>

3 个答案:

答案 0 :(得分:0)

想法

您可以将字符串拆分为已存在的锚点,并仅解析其间的片段。

守则

$input = '<a href="http://www.example.com">test</a> http://www.example.com';

// Split the string at existing anchors
// PREG_SPLIT_DELIM_CAPTURE flag includes the delimiters in the results set
$parts = preg_split('/(<a.*?>.*?<\/a>)/is', $input, PREG_SPLIT_DELIM_CAPTURE);

// Use array_map to parse each piece, and then join all pieces together
$output = join(array_map(function ($key, $part) {

    // Because we return the delimiter in the results set,
    // every $part with an uneven key is an anchor.
    return $key % 2
        ? preg_replace("/((https?:\/\/[\w]+[^ \,\"\n\r\t<]*))/is", "<a href=\"$1\">$1</a>", $part)
        : $part;
}, array_keys($parts), $parts);

答案 1 :(得分:0)

你可能会与 lookarounds 相处。 Lookarounds是零宽度断言,确保匹配/不匹配相关字符串周围的任何内容。他们不消耗任何字符 话虽如此,在您的情况下,您可能需要负面的背后隐藏

(?<![">])\bhttps?://\S+\b

PHP中,这将是:

<?php
$string = 'I want to be transformed to a proper link: http://www.google.com ';
$string .=  'But please leave me alone ';
$string .= '(<a href="https://www.google.com">https://www.google.com</a>).';

$regex = '~                # delimiter
              (?<![">])    # a neg. lookbehind
              https?://\S+ # http:// or https:// followed by not a whitespace
              \b           # a word boundary
          ~x';             # verbose to enable this explanation.
$string = preg_replace($regex, "<a href='$0'>$0</a>", $string);
echo $string;
?>

查看 ideone.com 上的演示。但是,parser可能更合适。

答案 2 :(得分:0)

由于你可以在preg_replace中使用Arrays,这可能会很方便使用,具体取决于你想要实现的目标:

  # @return [Boolean]
  # #
  def is_valid?(coupon)
    return false unless coupon.present?

    coupon_retrieved = Stripe::Coupon.retrieve(coupon)
    coupon_retrieved.valid == true

  rescue => error
    puts "#{error.class} :: #{error.message}"
    false
  end