在 PHP 中,基于 preg_replace 替换一段字符串中的一些敏感字符
1、在 PHP 中,基于 preg_replace 替换一段字符串中的一些敏感字符。存在的一个问题是,其格式中,可能某一段字符串是不存在的。示例如下
订单备注: 修改为: 是搜索 订单备注: 修改为: 13123123,订单发货备注: 修改为: 321312312 订单发货备注: 修改为: 87987
订单备注:***修改为:*** 订单备注:***修改为:***,订单发货备注:***修改为:*** 订单发货备注:***修改为:***
2、为何存在如上 3 种格式,原因在于其是基于如下代码生成的
$value = []; if ($order['remarks'] != $latestOrder['remarks']) { $value[] = sprintf( '订单备注由%s变更为%s', $order['remarks'], $latestOrder['remarks'] ); } if ($order['remarks_delivery'] != $latestOrder['remarks_delivery']) { $value[] = sprintf( '订单发货备注由%s变更为%s', $order['remarks_delivery'], $latestOrder['remarks_delivery'] ); } if (!empty($value)) { $data[OrderLogConstants::ORDER_REMARK] = implode(',', $value); }
3、最终实现的代码如下
$originalDescription = $description; $description = preg_replace('/(订单备注:)[\s\S]*修改为:[\s\S]*(,订单发货备注:)/', '$1***修改为:***,订单发货备注:', $description); if ($originalDescription == $description) { $description = preg_replace('/(订单备注:)[\s\S]*修改为:[\s\S]*/', '$1***修改为:***', $description); } $description = preg_replace('/(订单发货备注:)[\s\S]*修改为:[\s\S]*/', '$1***修改为:***', $description);
4、但是,当存在的格式有更多种的时候,比如说超过 10 种以上,在程序中硬编码就不可行了。决定抽象出一个方法
$value = []; if (trim($order['customer_name']) != trim($latestOrder['customer_name'])) { $value[] = sprintf( '客户姓名由%s变更为%s', $order['customer_name'], $latestOrder['customer_name'] ); } if ($order['customer_email'] != $latestOrder['customer_email']) { $value[] = sprintf( '联系邮箱由%s变更为%s', $order['customer_email'], $latestOrder['customer_email'] ); } if ($order['customer_tel'] != $latestOrder['customer_tel']) { $value[] = sprintf( '联系电话由%s变更为%s', $order['customer_tel'], $latestOrder['customer_tel'] ); } if ($order['customer_country_code'] != $latestOrder['customer_country_code']) { $value[] = sprintf( '所属国家由%s变更为%s', $order['customer_country'], $latestOrder['customer_country'] ); } if ($order['customer_state'] != $latestOrder['customer_state']) { $value[] = sprintf( '省/州由%s变更为%s', $order['customer_state'], $latestOrder['customer_state'] ); } if ($order['customer_city'] != $latestOrder['customer_city']) { $value[] = sprintf( '所属城市由%s变更为%s', $order['customer_city'], $latestOrder['customer_city'] ); } if ($order['customer_zip'] != $latestOrder['customer_zip']) { $value[] = sprintf( '邮编由%s变更为%s', $order['customer_zip'], $latestOrder['customer_zip'] ); } if (trim($order['customer_address1']) != trim($latestOrder['customer_address1'])) { $value[] = sprintf( '邮寄地址由%s变更为%s', $order['customer_address1'], $latestOrder['customer_address1'] ); } if (trim($order['customer_address2']) != trim($latestOrder['customer_address2'])) { $value[] = sprintf( '备用地址由%s变更为%s', $order['customer_address2'], $latestOrder['customer_address2'] ); } if ($order['customer_house_number'] != $latestOrder['customer_house_number']) { $value[] = sprintf( '门牌号由%s变更为%s', $order['customer_house_number'], $latestOrder['customer_house_number'] ); } if (trim($order['customer_abnnumber']) != trim($latestOrder['customer_abnnumber'])) { $value[] = sprintf( '收件人税号由%s变更为%s', $order['customer_abnnumber'], $latestOrder['customer_abnnumber'] ); } if (trim($order['customer_billing_address']) != trim($latestOrder['customer_billing_address'])) { $value[] = sprintf( '账单地址由%s变更为%s', $order['customer_billing_address'], $latestOrder['customer_billing_address'] ); } if (!empty($value)) { $data[OrderLogConstants::ORDER_CUSTOMER] = implode(',', $value); }
$patterns = ['客户姓名:', '联系邮箱:', '联系电话:', '所属国家:', '省/州:', '所属城市:', '邮编:', '邮寄地址:', '备用地址:', '门牌号:', '收件人税号:', '账单地址:']; $pattern = '修改为:'; /** * 对 日志的描述 加密 * @param string $description * @param array $patterns * @param string $pattern 要搜索的中间的模式 * @param array $onePatterns 要搜索的仅替换1处的模式数组 * @param string $oneSpacePattern 要搜索的仅替换1处的模式的间隔符 * @param array $noEncryptPatterns 要搜索的不加密的模式数组 * @return string */ private function encrypt(string $description, array $patterns, string $pattern = '变更为', array $onePatterns = [], string $oneSpacePattern = ',', array $noEncryptPatterns = []): string { foreach ($patterns as $key => $otherPattern) { unset($patterns[$key]); $description = $this->encryptCommonChange($description, $otherPattern, array_values($patterns), $pattern, $onePatterns, $oneSpacePattern, $noEncryptPatterns); } return $description; } /** * 对 简单的、公共的 加密的更改,避免穷举遍历(替换1处|不加密|替换2处) * @param string $description * @param string $startPattern 要搜索的开头的模式 * @param array $otherPatterns 要搜索的其他模式 * @param string $pattern 要搜索的中间的模式 * @param array $onePatterns 要搜索的仅替换1处的模式数组 * @param string $oneSpacePattern 要搜索的仅替换1处的模式的间隔符 * @param array $noEncryptPatterns 要搜索的不加密的模式数组 * @return string */ private function encryptCommonChange(string $description, string $startPattern, array $otherPatterns, string $pattern = '变更为', array $onePatterns = [], string $oneSpacePattern = ',', array $noEncryptPatterns = []): string { $originalDescription = $description; if (in_array($startPattern, $onePatterns)) { foreach ($otherPatterns as $otherPattern) { if ($originalDescription == $description) { $description = preg_replace('/(' . preg_quote($startPattern, '/') . ')[\s\S]*(' . $oneSpacePattern . preg_quote($otherPattern, '/') . ')/', '$1***' . $oneSpacePattern . $otherPattern, $description); } } if ($originalDescription == $description) { $description = preg_replace('/(' . preg_quote($startPattern, '/') . ')[\s\S]*/', '$1***', $description); } } elseif (in_array($startPattern, $noEncryptPatterns)) { // 不加密 } else { foreach ($otherPatterns as $otherPattern) { if ($originalDescription == $description) { $description = preg_replace('/(' . preg_quote($startPattern, '/') . ')[\s\S]*' . $pattern . '[\s\S]*(,' . preg_quote($otherPattern, '/') . ')/', '$1***' . $pattern . '***,' . $otherPattern, $description); } } if ($originalDescription == $description) { $description = preg_replace('/(' . preg_quote($startPattern, '/') . ')[\s\S]*' . $pattern . '[\s\S]*/', '$1***' . $pattern . '***', $description); } } return $description; }
5、最终替换前与替换后的格式对比如下,符合预期。如图1
客户姓名:常刚修改为:Daly Siennaa,联系邮箱:o.neyandezy@dsydyb.ga修改为:heodloklrs@iubridge.com,邮编:修改为:40291,联系电话:修改为:3421732762,所属城市:修改为:Louisville,邮寄地址:修改为:1214 Montreal Road 客户姓名:***修改为:***,联系邮箱:***修改为:***,邮编:***修改为:***,联系电话:***修改为:***,所属城市:***修改为:***,邮寄地址:***修改为:*** 联系电话:4913106683312修改为:1(310)668-3312,省/州:修改为:New York,邮寄地址:Amsterdam Ave Apt 214修改为:Amsterdam Ave 509 Apt 214 联系电话:***修改为:***,省/州:***修改为:***,邮寄地址:***修改为:***
近期评论