PHPでは、 MB_EREGI_REPLACEは、マルチバイト文字列の定期的な交換機能であり、ケース非感受性マッチングをサポートしています。これは、POSIX正規表現の構文に基づいているため、PCRE( PREG_*シリーズ関数)のような名前のグループ化をサポートしていません。名前のグループ化により、コードのメンテナンスと読み取りを容易にするために、正規表現の特定の部分の意味のある名前が可能になります。
この記事では、 MB_EREGI_REPLACEは名前付きグループ化をネイティブにサポートしていませんが、名前付きグループ化の効果をシミュレートする方法を紹介しますが、いくつかの回避策を使用して名前付きグループの効果をシミュレートできます。
MB_EREGI_REPLACEで使用される通常の構文は、 (?<name>パターン)などのPCREスタイルの名前のグループ化をサポートしておらず、数字以外のグループ識別子をサポートしていません。
例:
$pattern = '([a-z]+)'; // 通常のグループ化
しかし、それは次のように書くことはできません:
$pattern = '(?<word>[a-z]+)'; // 名前付きのグループ化はサポートされていません
したがって、特定のグループの内容を参照する必要がある場合は、 \ 1 、 \ 2などの数値インデックスを介してのみインデックスを作成できます。
MB_EREGI_REPLACEは名前のグループ化を直接使用することはできませんが、グループ化および交換中にコールバック関数と組み合わせてシミュレートできます。
ただし、 MB_EREGI_REPLACE自体にはコールバックバージョンがありません。まず、 MB_EREG_Searchシリーズ関数を使用して、一致し、グループ化コンテンツをキャプチャしてから、PHPに交換ロジックを実装できます。
サンプルフロー:
文字列を1つずつ一致させるには、 MB_EREG_SEARCH_INITとMB_EREG_SEARCHを使用してください。
各一致の後、グループ化コンテンツが取得され、手動で置き換えられます。
PHPアレイを使用して、指定されたグループの構造をシミュレートします。
次のコードは、 MB_EREG_Searchシリーズ関数を使用してグループ化コンテンツをキャプチャし、名前付きグループ化をシミュレートし、完全な交換をキャプチャする方法を示しています。
<?php
// 保留中の文字列
$text = "User: alice, Email: alice@example.com";
// POSIX スタイルの規則性,2つのグループ,ユーザー名と電子メール
$pattern = 'User: ([a-z]+), Email: ([a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,})';
// 検索を初期化します
mb_ereg_search_init($text, $pattern, 'i'); // i症例が鈍感であることを示します
$result = '';
$offset = 0;
while ($match = mb_ereg_search_pos()) {
// 試合の開始位置と長さを取ります
list($start, $length) = $match;
// 完全な一致する文字列を取得します
$fullMatch = mb_substr($text, $start, $length);
// キャプチャされたグループ化コンテンツを取得します
$regs = mb_ereg_search_getregs();
// 名前付きグループ化をシミュレートします
$namedGroups = [
'username' => $regs[1],
'email' => $regs[2],
];
// 交換ロジックを処理します,たとえば、ユーザー名を大文字にします,メールの隠された部分
$replacement = "User: " . strtoupper($namedGroups['username']) . ", Email: " . maskEmail($namedGroups['email']);
// スプライシング結果
$result .= mb_substr($text, $offset, $start - $offset) . $replacement;
$offset = $start + $length;
// 検索を続けます
mb_ereg_search_setpos($offset);
}
// 残りの部分をスプライシングします
$result .= mb_substr($text, $offset);
echo $result;
// ヘルパー機能,メールセクションを非表示にします
function maskEmail($email) {
$parts = explode('@', $email);
$name = $parts[0];
$domain = $parts[1];
$maskedName = substr($name, 0, 1) . str_repeat('*', max(0, strlen($name) - 2)) . substr($name, -1);
return $maskedName . '@' . $domain;
}
?>
MB_EREGI_REPLACEはコールバックを直接使用できないため、 MB_EREG_SEARCH_INITと関連関数を使用して、ループマッチングを実現し、代替品を手動で処理します。
$ regsアレイを使用して、グループ化コンテンツをキャプチャし、配列キー名を介して「名前付きグループ化」をシミュレートして、コードをより明確にします。
交換プロセスは完全にPHPコードで処理され、任意の複雑なロジックを実装できます。
この例では、ユーザー名の大文字化とメールボックス内のいくつかの文字を隠すことが実装されています。
MB_EREG_REPLACE FUNCTION自体は、PHPコード処理と組み合わせたMB_EREG_Searchシリーズ関数を使用して、名前付きグループ化をサポートしていませんが、同様の名前のグループ化効果を実現し、コードの読みやすさとメンテナンスを強化することができます。
より複雑な通常の機能と名前付きグループサポートが必要な場合は、 preg_replace_callbackを使用することをお勧めしますが、 MB_EREGファミリーほど強力なマルチバイトエンコードをサポートしていません。