没有不值得去解决的问题,也没有不值得去学习的技术!

Replace Sensitive Characters in a String With preg_replace in PHP

The format comparison before and after the final replacement is as follows, which meets expectations

1. In PHP, use preg_replace to replace sensitive characters in a string. One problem is that a specific segment of the string might not exist. Examples are as follows:

Plaintext
Order notes: Modified to: Yes search

Order notes: Modified to: 13123123, Order shipping notes: Modified to: 321312312

Order shipping notes: Modified to: 87987

Plaintext
Order notes:***Modified to:***

Order notes:***Modified to:***,Order shipping notes:***Modified to:***

Order shipping notes:***Modified to:***

2. The reason these 3 formats exist is that they are generated based on the following code:

PHP

$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. The final implemented code is as follows:

PHP

$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. However, when there are more formats, such as over 10, hardcoding them in the program becomes unfeasible. I decided to abstract a method:

PHP


$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);
}

PHP

$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. The format comparison before and after the final replacement is as follows, which meets expectations. See Figure 1:

The format comparison before and after the final replacement is as follows, which meets expectations
Figure 1
Plaintext
Customer name:Chang Gang Modified to: Daly Siennaa,Contact email:o.neyandezy@dsydyb.ga Modified to: heodloklrs@iubridge.com,Zip code: Modified to: 40291,Contact phone: Modified to: 3421732762,City: Modified to: Louisville,Shipping address: Modified to: 1214  Montreal Road
Customer name:***Modified to:***,Contact email:***Modified to:***,Zip code:***Modified to:***,Contact phone:***Modified to:***,City:***Modified to:***,Shipping address:***Modified to:*** 

Contact phone:4913106683312 Modified to: 1(310)668-3312,Province/State: Modified to: New York,Shipping address:Amsterdam Ave Apt 214 Modified to: Amsterdam Ave 509 Apt 214
Contact phone:***Modified to:***,Province/State:***Modified to:***,Shipping address:***Modified to:***

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系