1

この問題の最適な解決策を見つけることができませんでした。アイデアは、特定のドメインを含むテキストのすべてのURLをpreg_replace_callback()base64コード化に変更することです。URLはこのタイプです:http://www.domain.com/?fsdf76sf8sf6fdsそして別の方法で:http://www.otherdomain.com/file/CA60D10F8ACF7CAA

正規表現のアイデアはありますか?

4

2 に答える 2

1

あなたが探しているのは、

$s = preg_replace_callback('#(([a-z]+://)|([a-z]+://)?[a-z0-9.-]+\.|\b)domain.com[^\s]+#i', function($match) {
    return base64_encode($match[0]);
}, $string);

その正規表現は少し混乱するかもしれないので、それを分解しましょう:

(  -- domain.com must be preceeded by either
  ([a-z]+://)   -- a protocol such as http://
  |
  ([a-z]+://)?[a-z0-9.-]+\.  -- possibly a protocol and definitely a subdomain
  |
  \b  -- word-break (prevents otherdomain.com from matching!)
)
domain.com  -- the actual domain you're looking for
[^\s]+  -- everything up to the next space (to include path, query string, fragment)

このようなものをテストするための非常にシンプルなシステム:

<?php

$strings = array(
    // positives
    'a http://www.domain.com/?fsdf76sf8sf6fds z' => 'a xxx z',
    'a www.domain.com/?fsdf76sf8sf6fds z' => 'a xxx z',
    'a http://domain.com/?fsdf76sf8sf6fds z' => 'a xxx z',
    'a domain.com/?fsdf76sf8sf6fds z' => 'a xxx z',
    // negatives
    'a http://www.otherdomain.com/file/CA60D10F8ACF7CAA z' => null,
    'a www.otherdomain.com/file/CA60D10F8ACF7CAA z' => null,
    'a http://otherdomain.com/file/CA60D10F8ACF7CAA z' => null,
    'a otherdomain.com/file/CA60D10F8ACF7CAA z' => null,
);

foreach ($strings as $string => $result) {
    $s = preg_replace_callback('#(([a-z]+://)|([a-z]+://)?[a-z0-9.-]+\.|\b)domain.com[^\s]+#i', function($match) {
        return 'xxx';
    }, $string);

    if (!$result) {
        $result = $string;
    }

    if ($s != $result) {
        echo "FAILED: '$string' got '$s'\n";
    } else {
        echo "OK: '$string'\n";
    }
}

(すでにユニットテストを行っている場合は、代わりにそれを使用してください、明らかに…)

于 2012-06-30T12:42:05.347 に答える
1

この回答は、「http://www.domain.com/」または「https://www.domain.com/」で始まるURLでのみ機能しますが、はるかにスリムです。

$in = 'before http://www.domain.com/?fsdf76sf8sf6fds after';

$domain = 'www.domain.com';
echo preg_replace_callback('/\b(https?:\/\/'.preg_quote($domain).'\/)\?(\w+)/i', function($m) {
    return 'http://www.otherdomain.com/file/'.base64_encode($m[2]);
}, $in);
// outputs "before http://www.otherdomain.com/file/ZnNkZjc2c2Y4c2Y2ZmRz after"

まだ解決されていない問題の1つは、「CA60D10F8ACF7CAA」のサンプル出力が、PHPのbase64_encode()が返すものとは異なるbase64エンコード出力を示していることです。

echo base64_encode('fsdf76sf8sf6fds'); // outputs ZnNkZjc2c2Y4c2Y2ZmRz
于 2012-06-30T12:59:25.283 に答える