我需要實作一個 preg_replace 來修復我對大量腳本的一些警告。
我的目標是替換諸如...
$variable[key] = "WhatElse";
$result = $wso->RSLA("7050", $vegalot, "600", "WFID_OK_WEB","1300", $_POST[username]);
if ($result[ECD] != 0) {
if ($line=="AAAA" && in_array(substr($wso->lot,0,7),$lot_aaaa_list) && $lot[wafer][25]) {
...具有相同的陳述句,將常量替換為陣列鍵......
$variable['key'] = "WhatElse";
$result = $wso->RSLA("7050", $vegalot, "600", "WFID_OK_WEB","1300", $_POST['username']);
if ($result['ECD'] != 0) {
if ($line=="AAAA" && in_array(substr($wso->lot,0,7),$lot_aaaa_list) && $lot[wafer][25]) {
但不包括在字串中宣告陣列變數的情況,即...
$output = "<input name='variable[key]' has to be preserved as it is.";
$output = 'Even this string variable[key] has to be preserved as it is.';
...因為它們會被替換(但這不是我想要的):
$output = "<input name='variable['key']' has to be preserved as it is.";
$output = 'Even this string variable['key'] has to be preserved as it is.';
每個陳述句都由“preg_match_all”陳述句標識,然后替換為“str_replace”:
preg_match_all('/(\[(\w*)\])/', $str, $matches, PREG_SET_ORDER, 0);
$replace_str = $str;
$local_changeflag = false;
foreach($matches as $m) {
if (!$m[2]) continue;
if (is_numeric($m[2])) continue;
$replace_str = str_replace($m[1], "['" . $m[2] . "']", $replace_str);
$local_changeflag = true;
}
您有什么建議可以更好地解決我遇到的此類問題嗎?
uj5u.com熱心網友回復:
[我知道這不是正則運算式,但是由于您要求“建議更好地解決此類問題”,我給您 2 美分]
簡單地決議代碼怎么樣;):
$source = file_get_contents('/tmp/test.php'); // Change this
$tokens = token_get_all($source);
$history = [];
foreach ($tokens as $token) {
if (is_string($token)) { // simple 1-character token
array_push($history, str_replace(["\r", "\n"], '', $token));
$history = array_slice($history, -2);
echo $token;
} else {
list($id, $text) = $token;
switch ($id) {
case T_STRING:
if ($history == [T_VARIABLE, '[']) {
// Token sequence is [T_VARIABLE, '[', T_STRING]
echo "'$text'";
}
else {
echo $text;
}
break;
default:
// anything else -> output "as is"
echo $text;
break;
}
array_push($history, $id);
$history = array_slice($history, -2);
}
}
當然,$source需要更改為適合您的任何內容。token_get_all()然后加載 PHP 代碼并將其決議為令牌串列。然后根據我們的需要逐項處理該串列,并可能在再次輸出之前對其進行更改。
1-char 標記[(f.ex 中的“[”和“]”$myVariable[1]都成為標記)是一種特殊情況,必須在回圈中處理。否則 $token 是一個陣列,其中包含令牌型別和令牌本身的 ID。
“不幸的是”T_STRING是一種普遍情況,因此為了僅查明在陣列索引中用作常量的字串,我們將當前項之前的 2 項存盤在$history. ("$myVariable" 和 "[")
……而且……就是這樣,真的。代碼從檔案中讀取、處理并輸出到標準輸出。除了“常量作為陣列索引”之外的所有內容都應按原樣輸出。
如果您愿意,我可以將其重寫為函式或其他內容。不過,以上應該是一種通用的解決方案。
uj5u.com熱心網友回復:
如果要將任何有效識別符號包含在方括號內,可以preg_replace直接使用:
$regex = '/(["\'])(?:(?=(\\\\?))\2.)*?\1(*SKIP)(*F)|\[([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)]/s';
$ouptut = preg_replace($regex, '$3', $text);
請參閱正則運算式演示。詳情:
(["'])(?:(?=(\\?))\2.)*?\1- 匹配單引號或雙引號之間的字串(包含兩個捕獲組)(*SKIP)(*F)- 丟棄匹配的文本并且匹配失敗,從失敗位置開始新的搜索|- 或者\[-[字符([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)- 第 3 組:字母、下劃線或\x7f-\xff范圍中的任何字符,然后是任何字母數字、下劃線或\x7f-\xff范圍中的任何字符]- 一個]字符。
請參閱PHP 演示:
$regex = '/(["\'])(?:(?=(\\\\?))\2.)*?\1(*SKIP)(*F)|\[([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)]/s';
$str = '$output = "<input name=\'variable[key]\' has to be preserved as it is.";
$output = \'Even this string variable[key] has to be preserved as it is.\';
$variable[key] = "WhatElse";
$result = $wso->RSLA("7050", $vegalot, "600", "WFID_OK_WEB","1300", $_POST[username]);
if ($result[ECD] != 0) {
if ($line=="AAAA" && in_array(substr($wso->lot,0,7),$lot_aaaa_list) && $lot[wafer][25]) {';
echo preg_replace($regex, "['\$3']", $str);
輸出:
$output = "<input name='variable[key]' has to be preserved as it is.";
$output = 'Even this string variable[key] has to be preserved as it is.';
$variable['key'] = "WhatElse";
$result = $wso->RSLA("7050", $vegalot, "600", "WFID_OK_WEB","1300", $_POST['username']);
if ($result['ECD'] != 0) {
if ($line=="AAAA" && in_array(substr($wso->lot,0,7),$lot_aaaa_list) && $lot['wafer'][25]) {
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/389877.html
