在 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 联系电话:***修改为:***,省/州:***修改为:***,邮寄地址:***修改为:***

近期评论