序章
最初の私の一般的な問題は、文字列内の疑問符を文字列で置き換えたいということですが、それらが引用されていない場合のみです。そこで、SO (リンク)で同様の回答を見つけ、コードのテストを開始しました。残念ながら、もちろん、コードはエスケープされた引用符を考慮していません。
例えば:$string = 'hello="is it me your are looking for\\"?" AND test=?';
その回答から正規表現とコードを質問に適合させました: How to replace words outside double and single quotes、私の質問を読みやすくするためにここに再現されています:
<?php
function str_replace_outside_quotes($replace,$with,$string){
$result = "";
$outside = preg_split('/("[^"]*"|\'[^\']*\')/',$string,-1,PREG_SPLIT_DELIM_CAPTURE);
while ($outside)
$result .= str_replace($replace,$with,array_shift($outside)).array_shift($outside);
return $result;
}
?>
実際の問題
"
そのため、引用符ではないものとエスケープされた引用符に一致するようにパターンを調整しようとしました\"
:
<?php
$pattern = '/("(\\"|[^"])*"' . '|' . "'[^']*')/";
// when parsed/echoed by PHP the pattern evaluates to
// /("(\"|[^"])*"|'[^']*')/
?>
しかし、これは私が望んでいたようには機能しません。
私のテスト文字列は次のとおりです。hello="is it me your are looking for\"?" AND test=?
そして、私は次の一致を得ています:
array
0 => string 'hello=' (length=6)
1 => string '"is it me your are looking for\"?"' (length=34)
2 => string '?' (length=1)
3 => string ' AND test=?' (length=11)
一致インデックス 2 は存在しないはずです。このクエスチョン マークは、一致インデックス 1 の一部としてのみ考慮し、個別に繰り返さないでください。
この同じ修正が解決されたら、単一引用符/アポストロフィのメインの代替の反対側も修正する必要があります'
。
これが完全な関数によって解析された後、次のように出力されます。
echo str_replace_outside_quotes('?', '%s', 'hello="is it me your are looking for\\"?" AND test=?');
// hello="is it me your are looking for\"?" AND test=%s
これが理にかなっていることを願っており、質問に答えるのに十分な情報を提供しました. そうでない場合は、必要なものを喜んで提供します。
コードをデバッグする
私の現在の(完全な)コードサンプルは、フォーク用のコードパッドにもあります:
function str_replace_outside_quotes($replace, $with, $string){
$result = '';
var_dump($string);
$pattern = '/("(\\"|[^"])*"' . '|' . "'[^']*')/";
var_dump($pattern);
$outside = preg_split($pattern, $string, -1, PREG_SPLIT_DELIM_CAPTURE);
var_dump($outside);
while ($outside) {
$result .= str_replace($replace, $with, array_shift($outside)) . array_shift($outside);
}
return $result;
}
echo str_replace_outside_quotes('?', '%s', 'hello="is it me your are looking for\\"?" AND test=?');
サンプル入力と期待される出力
In: hello="is it me your are looking for\\"?" AND test=? AND hello='is it me your are looking for\\'?' AND test=? hello="is it me your are looking for\\"?" AND test=?' AND hello='is it me your are looking for\\'?' AND test=?
Out: hello="is it me your are looking for\\"?" AND test=%s AND hello='is it me your are looking for\\'?' AND test=%s hello="is it me your are looking for\\"?" AND test=%s AND hello='is it me your are looking for\\'?' AND test=%s
In: my_var = ? AND var_test = "phoned?" AND story = 'he said \'where is it?!?\''
Out: my_var = %s AND var_test = "phoned?" AND story = 'he said \'where is it?!?\''