9

特殊文字の有無にかかわらず特定の文字列に一致する正規表現はありますか? いわば、特殊文字を区別しない。

likecéraは に一致ceraし、その逆も同様です。

何か案は?

編集:特定の文字列を特殊文字/アクセント文字の有無にかかわらず一致させたい。文字列/文字だけではありません。

テスト例:

$clientName   = 'céra';
$this->search = 'cera';

$compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName));
$this->search      = strtolower($this->search);

if (strpos($compareClientName, $this->search) !== false)
{
    $clientName = preg_replace('/(.*?)('.$this->search.')(.*?)/iu', '$1<span class="highlight">$2</span>$3', $clientName);
}

出力:<span class="highlight">céra</span>

ご覧のとおり、特定の検索文字列を強調表示したいと思います。ただし、一致した文字列の元の (アクセント付きの) 文字を引き続き表示したいと考えています。

これをマイケル・シヴォロボフの答えと何らかの形で組み合わせる必要があると思います。

preg_match()別のとで作業する必要があると思いますよpreg_replace()ね?

4

4 に答える 4

9

パターンを使用して、\p{L}任意の文字に一致させることができます。

ソース

uUnicode モードを有効にするには、正規表現の後に修飾子を使用する必要があります。

例 :/\p{L}+/u

編集 :

このようなことを試してください。アクセント付きの文字 (単一文字と Unicode デュアルの両方) とアクセントのない文字を含む検索パターンに対して、すべての文字をアクセント付きで置き換える必要があります。その後、修正された検索パターンを使用してテキストを強調表示できます。

function mbStringToArray($string)
{
    $strlen = mb_strlen($string);
    while($strlen)
    {
        $array[] = mb_substr($string, 0, 1, "UTF-8");
        $string = mb_substr($string, 1, $strlen, "UTF-8");
        $strlen = mb_strlen($string);
    }
    return $array;
}

// I had to use this ugly function to remove accents as iconv didn't work properly on my test server.
function stripAccents($stripAccents){
    return utf8_encode(strtr(utf8_decode($stripAccents),utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'),'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY'));
}

$clientName = 'céra';

$clientNameNoAccent = stripAccents($clientName);

$clientNameArray = mbStringToArray($clientName);

foreach($clientNameArray as $pos => &$char)
{
    $charNA =$clientNameNoAccent[$pos];
    if($char != $charNA)
    {
        $char = "(?:$char|$charNA|$charNA\p{M})";
    }
}

$clientSearchPattern = implode($clientNameArray); // c(?:é|e|e\p{M})ra

$text = 'the client name is Céra but it could be Cera or céra too.';

$search = preg_replace('/(.*?)(' . $clientSearchPattern . ')(.*?)/iu', '$1<span class="highlight">$2</span>$3', $text);

echo $search; // the client name is <span class="highlight">Céra</span> but it could be <span class="highlight">Cera</span> or <span class="highlight">céra</span> too.
于 2013-09-26T08:33:58.380 に答える
7

文字にアクセントや別のマークがあるかどうかを知りたい場合は、パターンを一致させることで確認できます\p{M}

アップデート

パターン内のすべてのアクセント付き文字を代替グループに変換する必要があります。

例えばcéra -> c(?:é|e|e\p{M})ra

なぜ追加したのe\p{M}ですか?文字 é は Unicode の 1 文字であり、2 つの文字 (e とアクセント記号) の組み合わせである可能性があるためです。グレイブ アクセント付きの e (2 つの個別の Unicode 文字)にe\p{M}一致します。

すべての文字に一致するようにパターンを変換すると、それをpreg_match

于 2013-09-26T08:42:24.057 に答える
3

コメントの1つにマークを付けたように、目標は特定の文字列を見つけることであるため、そのための正規表現は必要ありません。なぜあなたは使わないのですexplodeか?そのように:

$clientName   = 'céra';
$this->search = 'cera';

$compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName));
$this->search      = strtolower($this->search);

$pieces = explode($compareClientName, $this->search);

if (count($pieces) > 1)
{
    $clientName = implode('<span class="highlight">'.$clientName.'</span>', $pieces);
}

編集:

変数に特殊文字も含まれている可能性がある場合$searchは、なぜtranslitそれを使用mb_strposしないの$offsetですか? このような:

$offset = 0;
$highlighted = '';
$len = mb_strlen($compareClientName, 'UTF-8');
while(($pos = mb_strpos($this->search, $compareClientName, $offset, 'UTF-8')) !== -1) {
    $highlighted .= mb_substr($this->search, $offset, $pos-$offset, 'UTF-8').
         '<span class="highlight">'.
         mb_substr($this->search, $pos, $len, 'UTF-8').'</span>';
    $offset = $pos + $len;
}
$highlighted .= mb_substr($this->search, $offset, 'UTF-8');

更新 2:

mb_シンプルなどの代わりに関数を使用することが重要ですstrlen。これは、アクセント付きの文字が 2 バイト以上を使用して格納されるためです。また、常に正しいエンコーディングを使用していることを確認してください。たとえば、次の例をご覧ください。

echo strlen('é');
> 2

echo mb_strlen('é');
> 2

echo mb_internal_encoding();
> ISO-8859-1

echo mb_strlen('é', 'UTF-8');
> 1

mb_internal_encoding('UTF-8');
echo mb_strlen('é');
> 1
于 2013-09-26T10:25:21.377 に答える
2

ここでわかるPOSIX equivalence classように、以下の正規表現で実行できる同じ照合順序で文字を照合するためのものです。

[=a=]

これは、ロケールに応じて一致áします。äa

于 2013-09-26T10:14:24.330 に答える