0

PHP のstrlen()関数は UTF-8 に対応していないため、 の各使用法を UTF-8 対応の対応するものと交換したいと思いますstrlen(): mb_strlen(). ただし、mb_strlen()追加の引数が必要です。

$length = strlen($someString);
$length = mb_strlen($someString, 'UTF-8');

2 番目の引数がなければ、単純な Perl 正規表現がスワップを処理します。

$ find . -name '*' -print0 | xargs -0 perl -pi -e 's/strlen/mb_strlen/g'

キャプチャ グループと後方参照を使用してみましたが、VIM スタイルの構文は (最近の Ubuntu では) サポートしていないか、理解できません。これについていくつかのバリエーションを試しましたが、成功しませんでした:

$ find . -name '*' -print0 | xargs -0 perl -pi -e 's/strlen\((\.*)\)/mb_strlen\($1, "UTF-8"\)/g'

trim()さらに、内部などの関数がある可能性があるstrlen()ため、これを貪欲にする必要がありますが、貪欲な演算子がどこに行くべきか正確にはわかりません。この正規表現はどのように記述すればよいですか?

4

4 に答える 4

1

これは、最初に表示されるよりも困難です。次のいずれかが必要です。

  1. 式の複数行バージョンを含め、式を適切に解析します。
  2. 浮気

私はチートに行きます。

strlen() 呼び出しのほとんどは非常に単純で、残りのいくつかは手動で置き換えることができます。そして、ある種のバージョン管理の下でこれを行っていますよね:

シンプル: strlen("foo"), strlen($bar)

# Match simple quoted strings - no embedded quotes
s/strlen\((["'][^"']*["'])\)/mb_strlen($1, 'UTF-8')/g
# Match simple variables - no method calls etc
s/strlen\((\$\w+)\)/mb_strlen($1, 'UTF-8')/g

配列変数、関数とメソッドの呼び出し、およびその他の式の処理はより複雑になりますが、これら 2 つの基本的な置換の後にどれだけ残っているかを確認してください。

于 2013-02-01T09:08:26.080 に答える
0

単純な正規表現では、一般的なケースでは問題を解決できません。次の例を検討してください。

if (strlen($var) > 0)

$total_length = strlen($thing1) + strlen($thing2);

strlen($var);   #Don't use trim() here because it was already trimmed.

some_other_function(strlen($foo) + 2);

.*行の最後の閉じ括弧まですべてを貪欲にキャプチャするため、これらのいずれも正規表現では機能しません。これを正しく行う唯一の方法は、バランスの取れた括弧をチェックすることです。これは、正規表現では重要です(Perlの拡張正規表現機能を使用すると技術的には可能ですが、簡単な作業ではありません)。

上記のケースの多くに遭遇するとは思わない場合は、他の提案された解決策の1つを使用して、エラーを確認してください。または、これを実行して、括弧が含まれていない単純なケースをすべてキャッチすることもできます。

s/\bstrlen\(([^()]*)\)/mb_strlen($1, "UTF-8")/g

(注:\b単語の境界から始まることを確認するためにも追加しました。これにより、すでに存在するものを二重に置き換えることができなくなりますmb_strlen

ただし、すべての場合に機能する簡単なクイックハックソリューションがあります。追加の引数を追加しながらmy_mb_strlen呼び出す、などと呼ばれる独自のPHP関数を作成します。mb_strlen次に、はるかに簡単な検索を実行し、関数名のみを置き換えstrlenて、を置き換えることができますmy_mb_strlen

于 2013-02-01T09:13:58.290 に答える
0
find . -type f|xargs perl -pi -e 's/strlen\(([^\)]*)\)/mb_strlen($1,'UTF_8')/g'
于 2013-02-01T10:00:29.107 に答える
0

を指定する\.*と、正規表現は 0 個以上のリテラル'.'s に一致します。

を省略して試してみてください\:

s/strlen\((.*)\)/mb_strlen($1, "UTF-8")/g
           ^              ^           ^
           NO BACKSLASH   NO BACKSLASH NEEDED
                          AS THIS IS TREATED AS
                          A STRING AND NOT A REGEX

また、最初にフラグなしでテストし-iて、置換に満足していることを確認してください。そうしないと、ファイルがその場で変更されます。

于 2013-02-01T08:12:36.483 に答える