利用PHP将部分内容用星号替换


Posted in PHP onApril 21, 2020

在最近的项目中,会碰到到某人的手机号码隐藏中间几位,身份证号码只显示末尾4位的需求。当时一开始是网上搜索了一下,看到有人是用substr_replace这个函数来替换的,后面我也用了这个函数,但在用的时候不是很好用。

一、substr_replace

先来看看这个函数的语法:

substr_replace(string,replacement,start,length)
参数 描述
string 必需。规定要检查的字符串。
replacement 必需。规定要插入的字符串。
start 必需。规定在字符串的何处开始替换。  正数 - 在第 start 个偏移量开始替换  负数 - 在从字符串结尾的第 start 个偏移量开始替换  0 - 在字符串中的第一个字符处开始替换
charlist 可选。规定要替换多少个字符。 正数 - 被替换的字符串长度 负数 - 从字符串末端开始的被替换字符数 0 - 插入而非替换

1、当start与charlist都为正数的时候,非常好理解,也很符号人的逻辑,start是从0开始的,如下图,根据条件,绿色的将是要被替换的元素

利用PHP将部分内容用星号替换

2、当start为负数,charlist为正数的时候,也挺好理解的

利用PHP将部分内容用星号替换

3、当start为正数,charlist为负数的时候,这个我一开始理解错了

利用PHP将部分内容用星号替换

4、当start为负数,charlist为负数的时候,有一个地方需要注意的就是:如果 start 是负数且 length 小于等于 start,则 length 为 0。这个坑挺容易踩到的

利用PHP将部分内容用星号替换

5、charlist为0的时候,就变成插入了,而不是替换,额。。。

 

用下来,我是感觉不是很顺手,虽然说满足我现在的需求还是可以的,但是如果将来需要一些扩展的话,耍起来挺吃力的,所以就想到自己构造一个,将来用起来也方便。

二、自制的星号替换函数

replaceStar($str, $start, $length = 0)

利用PHP将部分内容用星号替换

前面的两个参数与上面的一样,最后的参数与上面不同

1、当start与length都为正数,与substr_replace表现的一样

2、当start为负数,length为正数,与substr_replace表现的一样

利用PHP将部分内容用星号替换

三、源码分享

public static function replaceStar($str, $start, $length = 0)
{
 $i = 0;
 $star = '';
 if($start >= 0) {
  if($length > 0) {
  $str_len = strlen($str);
  $count = $length;
  if($start >= $str_len) {//当开始的下标大于字符串长度的时候,就不做替换了
   $count = 0;
  }
  }elseif($length < 0){
  $str_len = strlen($str);
  $count = abs($length);
  if($start >= $str_len) {//当开始的下标大于字符串长度的时候,由于是反向的,就从最后那个字符的下标开始
   $start = $str_len - 1;
  }
  $offset = $start - $count + 1;//起点下标减去数量,计算偏移量
  $count = $offset >= 0 ? abs($length) : ($start + 1);//偏移量大于等于0说明没有超过最左边,小于0了说明超过了最左边,就用起点到最左边的长度
  $start = $offset >= 0 ? $offset : 0;//从最左边或左边的某个位置开始
  }else {
  $str_len = strlen($str);
  $count = $str_len - $start;//计算要替换的数量
  }
 }else {
  if($length > 0) {
  $offset = abs($start);
  $count = $offset >= $length ? $length : $offset;//大于等于长度的时候 没有超出最右边
  }elseif($length < 0){
  $str_len = strlen($str);
  $end = $str_len + $start;//计算偏移的结尾值
  $offset = abs($start + $length) - 1;//计算偏移量,由于都是负数就加起来
  $start = $str_len - $offset;//计算起点值
  $start = $start >= 0 ? $start : 0;
  $count = $end - $start + 1;
  }else {
  $str_len = strlen($str);
  $count = $str_len + $start + 1;//计算需要偏移的长度
  $start = 0;
  }
 }

 while ($i < $count) {
  $star .= '*';
  $i++;
 }

 return substr_replace($str, $star, $start, $count);
}

不擅长算法,这里就用很普通的逻辑来展示啦,没有用到啥数学公式。

1、if($start >= 0)这里做start大于等于0与小于0的分支

2、在start 的分之中,分别再做length 大于0,小于0和等于0的三个分支

3、最后计算出start、count和要替换的星号字符串,最后计算出的start与count都是正数,运用substr_replace做替换

 四、单元测试

public function testReplaceStar()
 {
 $actual = App_Util_String::replaceStar('123456789', 3, 2);
 $this->assertEquals($actual, '123**6789');
 
 $actual = App_Util_String::replaceStar('123456789', 9);
 $this->assertEquals($actual, '123456789');
 
 $actual = App_Util_String::replaceStar('123456789', 9, 2);
 $this->assertEquals($actual, '123456789');
 
 $actual = App_Util_String::replaceStar('123456789', 9, -9);
 $this->assertEquals($actual, '*********');
 
 $actual = App_Util_String::replaceStar('123456789', 9, -10);
 $this->assertEquals($actual, '*********');
 
 $actual = App_Util_String::replaceStar('123456789', 9, -11);
 $this->assertEquals($actual, '*********');
 
 $actual = App_Util_String::replaceStar('123456789', 3);
 $this->assertEquals($actual, '123******');
 
 $actual = App_Util_String::replaceStar('123456789', 0);
 $this->assertEquals($actual, '*********');
 
 $actual = App_Util_String::replaceStar('123456789', 0, 2);
 $this->assertEquals($actual, '**3456789');

 $actual = App_Util_String::replaceStar('123456789', 3, -3);
 $this->assertEquals($actual, '1***56789');
 
 $actual = App_Util_String::replaceStar('123456789', 1, -5);
 $this->assertEquals($actual, '**3456789');
 
 $actual = App_Util_String::replaceStar('123456789', 3, -3);
 $this->assertEquals($actual, '1***56789');
 
 $actual = App_Util_String::replaceStar('123456789', -3, 2);
 $this->assertEquals($actual, '123456**9');
 
 $actual = App_Util_String::replaceStar('123456789', -3, 5);
 $this->assertEquals($actual, '123456***');
 
 $actual = App_Util_String::replaceStar('123456789', -1, 2);
 $this->assertEquals($actual, '12345678*');
 
 $actual = App_Util_String::replaceStar('123456789', -1, -2);
 $this->assertEquals($actual, '1234567**');
 
 $actual = App_Util_String::replaceStar('123456789', -4, -7);
 $this->assertEquals($actual, '******789');
 
 $actual = App_Util_String::replaceStar('123456789', -1, -3);
 $this->assertEquals($actual, '123456***');
 
 $actual = App_Util_String::replaceStar('123456789', -1);
 $this->assertEquals($actual, '*********');
 
 $actual = App_Util_String::replaceStar('123456789', -2);
 $this->assertEquals($actual, '********9');
 
 $actual = App_Util_String::replaceStar('123456789', -9);
 $this->assertEquals($actual, '*23456789');
 
 $actual = App_Util_String::replaceStar('123456789', -10);
 $this->assertEquals($actual, '123456789');
 
 $actual = App_Util_String::replaceStar('123456789', -10, -2);
 $this->assertEquals($actual, '123456789');
 }

以上就是本文的全部内容,希望对大家的学习有所帮助。

PHP 相关文章推荐
php下尝试使用GraphicsMagick的缩略图功能
Jan 01 PHP
PHP中实现中文字符进制转换原理分析
Dec 06 PHP
php多维数组去掉重复值示例分享
Mar 02 PHP
PHP获取中英混合字符串长度的方法
Jun 07 PHP
PHP中读取照片exif信息的方法
Aug 20 PHP
PHP中使用匿名函数操作数据库的例子
Nov 17 PHP
php使用cookie保存登录用户名的方法
Jan 26 PHP
PHP使用PDO连接ACCESS数据库
Mar 05 PHP
php使用cookie实现记住登录状态
Apr 27 PHP
详解WordPress中添加和执行动作的函数使用方法
Dec 29 PHP
php函数传值的引用传递注意事项分析
Jun 25 PHP
tp5框架基于Ajax实现列表无刷新排序功能示例
Feb 10 PHP
php之static静态属性与静态方法实例分析
Jul 30 #PHP
php中define用法实例
Jul 30 #PHP
php实现json编码的方法
Jul 30 #PHP
php函数连续调用实例分析
Jul 30 #PHP
php数字运算验证码的实现代码
Jul 30 #PHP
文件上传之SWFUpload插件(代码)
Jul 30 #PHP
js代码实现微博导航栏
Jul 30 #PHP
You might like
解析php中call_user_func_array的作用
2013/06/07 PHP
解析php addslashes()与addclashes()函数的区别和比较
2013/06/24 PHP
标准版Eclipse搭建PHP环境的详细步骤
2015/11/18 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
jQuery ctrl+Enter shift+Enter实现代码
2010/02/07 Javascript
javascript框架设计读书笔记之数组的扩展与修复
2014/12/02 Javascript
自制微信公众号一键排版工具
2016/09/22 Javascript
微信小程序中做用户登录与登录态维护的实现详解
2017/05/17 Javascript
Bootstrap输入框组件使用详解
2017/06/09 Javascript
vue scroller返回页面记住滚动位置的实例代码
2018/01/29 Javascript
Vue.set() this.$set()引发的视图更新思考及注意事项
2018/08/30 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
Vue $mount实战之实现消息弹窗组件
2019/04/22 Javascript
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
Layer组件多个iframe弹出层打开与关闭及参数传递的方法
2019/09/25 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
2019/10/14 Javascript
如何配置vue.config.js 处理static文件夹下的静态文件
2020/06/19 Javascript
如何基于viewport vm适配移动端页面
2020/11/13 Javascript
python使用paramiko模块实现ssh远程登陆上传文件并执行
2014/01/27 Python
朴素贝叶斯算法的python实现方法
2014/11/18 Python
itchat接口使用示例
2017/10/23 Python
Python实现PS滤镜中马赛克效果示例
2018/01/20 Python
使用pygame模块编写贪吃蛇的实例讲解
2018/02/05 Python
Django 对IP访问频率进行限制的例子
2019/08/30 Python
python实现简单银行管理系统
2019/10/25 Python
详解使用django-mama-cas快速搭建CAS服务的实现
2019/10/30 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
2020/06/18 Python
纯CSS3实现鼠标滑过按钮动画第二节
2020/07/16 HTML / CSS
Linux的文件类型
2016/07/05 面试题
项目专员岗位职责
2013/12/04 职场文书
大学生党员自我剖析材料
2014/10/06 职场文书
北京英语导游词
2015/02/12 职场文书
复兴之路展览观后感
2015/06/02 职场文书
JavaScript的function函数详细介绍
2021/11/20 Javascript
详解JavaScript的计时器和按钮效果设置
2022/02/18 Javascript
Python自动化实战之接口请求的实现
2022/05/30 Python