4

余分なスペース (連続した空白文字のインスタンス) を 1 つのスペースに置き換えたいと思いますが、それらの余分なスペースが二重引用符または一重引用符 (または含めたい他の囲み) で囲まれていない場合に限ります。

同様の質問をいくつか見ましたが、上記の私のニーズに対する直接的な回答は見つかりませんでした。ありがとうございました!

4

2 に答える 2

2

まだ探しているか、戻ってきて確認してください。これは私にとってはうまくいくようです:

'/\s+((["\']).*?(?=\2)\2)|\s\s+/'

...と置き換えます $1

編集

\"また、またはのようなエスケープされた引用符を許可する必要がある場合は、次の\'式を使用できます。

 '/\s+((["\'])(\\\\\2|(?!\2).)*?(?=\2)\2)|\s\s+/'

ブラケットのような「バランスの取れた」引用符 (()または など{})のサポートを追加する場合は、少し粘着性があります。

編集終了

問題を見つけた場合、または説明が必要な場合はお知らせください。


願わくば最終編集と警告

  • 潜在的な問題: 引用符で囲まれた文字列が文字列変数 (またはファイル) の先頭から始まる場合、引用符で囲まれた文字列としてカウントされないか (空白が削減されます)、全体が破棄されて、引用符で囲まれていないものが作成されます。引用符で囲まれているかのように扱われ、その逆も同様です -
    • これを修正する可能性のある変更は、次の一致式を使用することです
    • /(?:^|\s+)((["\'])(\\\\\2|(?!\2).)*?(?=\2)\2)|\s\s+/
    • \s+これは式の(?:^|\s+)先頭に置き換わります
    • これにより、文字列が引用符で始まる場合、変数の先頭にスペースが追加されます-続行するには、trim() またはその空白を削除するだけです
  • 元の結果に到達するために「行ごと」のアプローチ(間違いでなければsedなど)を使用したようです-「ファイル全体」または「文字列全体」の設定またはアプローチ、キャリッジリターンを使用する場合-改行は2つの空白文字としてカウントされるようです(理由は想像できません...)。したがって、改行を単一のスペースに変換します(もちろん、引用符内にあり、「ドットマッチ-改行」が使用されている場合を除く)
    • .これは、次のように、および\s略記文字クラスを一致させたい特定の文字に置き換えることで解決できます。
    • /(?:^|[ \t]+)((["\'])(\\\\\2|(?!\2)[\s\S])*?(?=\2)\2)|[ \t]{2,}/
    • これは dot-matches - newline スイッチを必要とせず、改行ではなく複数のスペースまたはタブのみを単一のスペースに置き換えます(もちろん、それらが引用されていない場合のみ)

このリンクは、 http://codepad.viper-7.comのサンプル テキストで使用されている最初の式と最後の式の例を示しています。

于 2012-04-09T16:31:37.453 に答える
2

いくつかのステップでそれを行うことができます。次の例を検討してください。

$str = 'This is    a string with  "Bunch of    extra  spaces". Leave them  "untouched  !".';

$id = 0;
$buffer = array();
$str = preg_replace_callback('|".*?"|', function($m) use (&$id, &$buffer) {
    $buffer[] = $m[0];
    return '__' . $id++;
}, $str);
$str = preg_replace('|\s+|', ' ', $str);
$str = preg_replace_callback('|__(\d+)|', function($m) use ($buffer) {
    return $buffer[$m[1]];
}, $str);

echo $str;

これにより、次の文字列が出力されます。

This is a string with "Bunch of    extra  spaces". Leave them "untouched  !".

これは最も美しい解決策ではありませんが。

于 2012-04-09T14:42:04.903 に答える