1

私は正しい英語に固執しています (はい、「固執する」と「正しい」が矛盾していることは知っています)。会社のサイトで使用する CMS を作成しましたが、公開されたコンテンツに「スマートな」引用を作成するという、非常に神経質になっていることが 1 つあります。

それを行う正規表現がありますが、コピーでhtmlタグに遭遇すると問題が発生します。たとえば、私の CMS で使用されている公開済みのストーリーの 1 つに、多数のプレーン テキストといくつかの HTML タグ (リンク タグなど) が含まれている場合があります。これには、明白な理由から「スマート」引用符に変更したくない引用符が含まれています。 .

15 年前、私は Perl RegEx エースでしたが、これには完全に空白を描いています。私がやりたいことは、html タグ内のすべてのテキストを無視して文字列を処理し、文字列内のすべての引用符を「スマート」引用符に置き換えてから、html タグをそのままにして文字列を返すことです。

私は CMS で直面する最も一般的なシナリオを処理するために一緒に詰め込んだ関数を持っていますが、それが見苦しく、まったく洗練されていないこと、および予期しないタグが表示された場合にソリューションが完全に壊れることが嫌いです。

コードは次のとおりです(笑わないでください。スコッチのボトル半分以上を一緒に叩きつけたものです)。

function educate_quotes($string) {
        $pattern = array('/\b"/',//right double
                        '/"\b/',//left double
                        '/"/',//left double end of line
                        "/(\w+)'(\w+)/",//apostrophe
                        "/\b'/",//left single
                        "/'\b/",//right single
                        "/'$/",//right single end of line
                        "/--/"//emdash
                        );

        $replace = array("”",//right double quote
                        "“",//left double
                        "”",//left double end of line
                        "$1"."’"."$2",//apostrophe
                        "’",//left single
                        "‘",//right single
                        "’",//right single end of line
                        "—"//emdash
                        );

        $string =  preg_replace($pattern,$replace,$string);
        //remove smart quotes around urls
        $string = preg_replace("/href=“(.+)”/","href=\"$1\"",$string);
        //remove smart quotes around images
        $string = preg_replace("/src=“(.+?)”/","src=\"$1\" ",$string);
        //remove smart quotes around alt tags
        $string = str_replace('alt=”"','',$string);
        $pat = "/alt=“(.+?)”/is";
        $rep = "alt=\"$1\" ";
        $string = preg_replace($pat,$rep,$string);
        //i'm too lazy to figure out why this artifact keeps appearing
        $string = str_replace("alt=“",'alt="',$string);
        //same thing here
        $string = preg_replace("/” target/","\" target",$string);
        return $string;
    }

私が言ったように、私はコードが醜いことを知っており、より洗練されたソリューションに対してオープンです。動作しますが、将来、予期しないタグが来ると壊れます。記録のために、私は PARSE html タグへの正規表現を取得しようとしていないことを繰り返したいと思います。文字列内の残りのテキストをすべて解析しながら、それらを IGNORE にしようとしています。

解決策はありますか?私は多くのオンライン検索を行ってきましたが、解決策を見つけることができないようです.PHPの正規表現の実装に慣れていないため、驚くほどです.

4

3 に答える 3

0

わかった。SlacksがDOM解析を提案した後、私は自分の質問に答えましたが、作成された文字列で正規表現が機能しないという問題があります。これが私のコードです:

function educate_quotes($string) {  
        $pattern = array(
            '/"(\w+)"/',//quotes
            "/(\w+)'(\w+)/",//apostrophe
            "/'(\w+)'/",//single quotes
           "/'\b/",//right single
            "/--/"//emdash
        );

        $replace = array(
            "“"."$1"."”",//quotes
            "$1"."’"."$2",//apostrophe
            "’"."$1"."‘",//single quotes
            "‘",//right single
            "—"//emdash
        );

        $xml = new DOMDocument();
        $xml->loadHTML($string);
        $text = (string)$xml->textContent;
        $smart = preg_replace($pattern,$replace,$text);
        $xml->textContent = $smart; 
        $html = $xml->saveHTML();
        return $html;
    }

DOM 解析は正常に機能しています。問題は、私の正規表現(上記のものから変更しましたが、作成された新しい文字列で上記の正規表現が機能しなくなるまでは変更していません)が実際には文字列内の引用符を置き換えていないことです。

また、文字列に不完全な HTML コードがあると、次の厄介な警告が表示されます。

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: Unexpected end tag : p in Entity, line: 2 in /home/leifw/now/cms_functions.php on line 418

レポーターが常に完璧な HTML コードを使用するとは期待できないので、それも問題です。

于 2016-09-09T03:09:39.050 に答える
0

html タグに基づいて分割し< >、それを元に戻すことは可能ですか?

$text = "<div sdfas=\"sdfsd\" >ksdfsdf\"dfsd\" dfs </div> <span sdf='dsfs'> dfsd 'dsf ds' </span> ";
$new_text = preg_split("/(<.*?>)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
echo htmlspecialchars(print_r($new_text, 1));

あなたが得るものは次のとおりです:

Array
(
    [0] => 
    [1] => <div sdfas="sdfsd" >
    [2] => ksdfsdf"dfsd" dfs 
    [3] => </div>
    [4] =>  
    [5] => <span sdf='dsfs'>
    [6] =>  dfsd 'dsf ds' 
    [7] => </span>
    [8] =>  
)

次に、. がない場合は、preg_replace を使用して全体を元に戻すことができます< >

于 2016-09-09T07:00:23.630 に答える
0

A.ラウの提案を使用して、解決策があると思いますが、実際にはxmlパーサーではなく正規表現であることがわかりました。

これが私のコードです:

$string = '<p>"This" <b>is</b> a "string" with <a href="http://somewhere.com">quotes</a> in it. <img src="blah.jpg" alt="This is an alt tag"></p><p>Whatever, you know?</p>';

    $new_string = preg_split("/(<.*?>)/",$string, -1, PREG_SPLIT_DELIM_CAPTURE);

    echo "<pre>";
    print_r($new_string);
    echo "</pre>";

    for($i=0;$i<count($new_string);$i++) {
        $str = $new_string[$i];
        if ($str) {
            if (strpos($str,"<") === false) {
                $new_string[$i] = convert_quotes($str);
            }
        }
    }

    $str = join('',$new_string);
    echo $str; 

    function convert_quotes($string) {
        $pattern = array('/\b"/',//right double
                    '/"\b/',//left double
                    '/"/',//left double end of line
                    "/(\w+)'(\w+)/",//apostrophe
                    "/\b'/",//left single
                    "/'\b/",//right single
                    "/'$/",//right single end of line
                    "/--/"//emdash
                    );

        $replace = array("&#8221;",//right double quote
                    "&#8220;",//left double
                    "&#8221;",//left double end of line
                    "$1"."&#8217;"."$2",//apostrophe
                    "&#8217;",//left single
                    "&#8216;",//right single
                    "&#8217;",//right single end of line
                    "&#151;"//emdash
                    );
        return preg_replace($pattern,$replace,$string);
    }

そのコードは次を出力します。

配列 (

>     [0] => 
>     [1] => <p>
>     [2] => "This" 
>     [3] => <b>
>     [4] => is
>     [5] => </b>
>     [6] =>  a "string" with 
>     [7] => <a href="http://somewhere.com">
>     [8] => quotes
>     [9] => </a>
>     [10] =>  in it. 
>     [11] => <img src="blah.jpg" alt="This is an alt tag">
>     [12] => 
>     [13] => </p>
>     [14] => 
>     [15] => <p>
>     [16] => Whatever, you know?
>     [17] => </p>
>     [18] => >
> Whatever, you know?

「これ」は引用符を含む「文字列」です。これは代替タグです

何でも、あなたは知っていますか?

于 2016-09-10T04:50:00.427 に答える