2017-06-23 12 views
2

私はこの文章で特定のフレーズを強調するテキストがあります。強調表示は、太字のフレーズを<b>phrase</b>にすることによって行われます。PHP文字列内のフレーズをハイライト表示

私は、強調表示する必要があるフレーズで配列を作成しました。以下を参照してください:

私のフレーズを強調する機能を作成しました。私は次のテキストがある場合

function highlight_phrases($string, $phrases, $tag = 'strong') 
{ 
    foreach($phrases as $phrase) { 
     $string = preg_replace('/' . $phrase . '/i', '<' . $tag . '>$0</' . $tag . '>', $string); 
    }  
    return $string; 
} 

は今:

This is some text about the <strong>iPhone 7</strong> and this i really a nice peace of engineering. 

OK、すべての罰金:

This is some text about the iPhone 7 and this i really a nice peace of engineering. 

をこれがに変わります!

今、私は別のテキストを持っている:

We are now talking about the iPhone 7 Plus, which is very big! 

そして、ここでは間違っているもので、それはにこのターン:このHTMLが画面に印刷されている場合

We are now talking about the <strong><strong>iPhone 7</strong> Plus</strong>, which is very big! 

、それはちょうどよく見える。しかし、strongタグ内のstrongタグのため、コード自体が間違っています。

これをどのように修正できますか?

注:$phrases配列が非常に大きくなる場合がありますフレーズ

+2

これはPHPクラスの唯一の目的ですか?もしそうなら、あなたはクライアント側の解決策を考え出すことができます.JavaScriptを使うだけです。 – treecon

+1

あなたの 'for'ループを置き換える'/iphone 7 plus | iphone 7/i'のような正規表現を使う必要があります。 '$ ''、$ string('/'、$ phrase)'のように 'return preg_replace( '/'。 ); '(また、それらのフレーズを' preg_quote'し、最長のものが最初に来ることを確認することをお勧めします)。 –

+0

@treecon、私はまた、読みやすさと 'iphone 7'と' iphone 7 plus'の違いをより明確にするため、javascriptの使用について考えました。 – Timo002

答えて

1

あなたはまたpreg_quoteがアイテムをINGの間、動的に交代ベースの正規表現を構築する必要があります(自動的にすべての特殊正規表現メタキャラクターからエスケープしてください)、降順で長さ順に並べ替えます(そうしないと、短い部分文字列は元のコードと同じように長い部分文字列をマッチさせません)。問題の2つの検索フレーズの表現は、/iphone 7 plus|iphone 7/iのようになります。これは、あなたのforループを置き換えて、同じ用語を何度も一致させることができます。ここで

sample PHP demoです:

function highlight_phrases($string, $phrases, $tag = 'strong') 
{ 
    usort($phrases, function($a,$b){ 
     return strlen($b)-strlen($a); 
    }); 
    //print_r($phrases); // => Array ([0] => iphone 7 plus [1] => iphone 7) 
    $pattern = '/' . implode("|", array_map(function ($x) { 
     return preg_quote($x, '/'); 
    }, $phrases)) . '/i'; 
    // echo "$pattern"; // => /iphone 7 plus|iphone 7/i 
    return preg_replace($pattern, '<' . $tag . '>$0</' . $tag . '>', $string); 
} 

$phrases = ['iphone 7', 'iphone 7 plus']; 
$s = "This is some text about the iPhone 7 and this i really a nice peace of engineering. We are now talking about the iPhone 7 Plus, which is very big!"; 
echo highlight_phrases($s, $phrases); 
// => This is some text about the <strong>iPhone 7</strong> and this i really a nice peace of engineering. We are now talking about the <strong>iPhone 7 Plus</strong>, which is very big! 

パターンについての言葉のカップル:NFA正規表現では、非固定交代グループは、最長POSIX、とは異なり、一致を見つけた最初の代替ブランチにマッチマッチが捜されます。より長い検索フレーズが短いものの前に現れなければならない理由です。 Remember That The Regex Engine Is Eagerを参照してください。

0

あなたの機能は今無力ALS str_replace()

使用などにpreg_replace()を使用して、多分あなたが知っているすべての携帯電話がそれにあるかもしれませんこれは、必要に応じて「プラス」に続いて「iphone 7」の検索でしょう

$phrases = ['iphone 7(?: plus)?'];

:正規表現の力最後の疑問符は、()の間の部分をオプションにします。

(と:?。それは交換する機能の第二部では$ 2として表示されない可能 )

+0

私は '$ phrase"配列がこのアプローチでは難しくなるかもしれないと思います。正規表現知識を持たない人は配列を維持できなければなりません。 – Timo002

関連する問題