利用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+mysql实现无限级分类 | 树型显示分类关系
Nov 19 PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
Nov 30 PHP
php学习笔记 数组的常用函数
Jun 13 PHP
PHP 图片上传代码
Sep 13 PHP
php数字转汉字代码(算法)
Oct 08 PHP
php中使用session_set_save_handler()函数把session保存到MySQL数据库实例
Nov 06 PHP
PHP中使用Memache作为进程锁的操作类分享
Mar 30 PHP
php表单提交实例讲解
Nov 12 PHP
在CentOS系统上从零开始搭建WordPress博客的全流程记录
Apr 21 PHP
php函数mkdir实现递归创建层级目录
Oct 27 PHP
PHP数组内存利用率低和弱类型详细解读
Aug 10 PHP
Laravel 连接(Join)示例
Oct 16 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处理图片变得简单 基于gb库的图片处理类附实例代码下载
2011/05/17 PHP
PHP学习笔记(二) 了解PHP的基本语法以及目录结构
2014/08/04 PHP
php的4种常见运行方式
2015/03/20 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
JavaScript使用技巧精萃[代码非常实用]
2008/11/21 Javascript
基于jquery的图片的切换(以数字的形式)
2011/02/14 Javascript
jquery实现滑动图片自己测试的例子
2013/11/05 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
通过javascript进行UTF-8编码的实现方法
2016/06/27 Javascript
jQuery Ajax 加载数据时异步显示加载动画
2016/08/01 Javascript
JS对大量数据进行多重过滤的方法
2016/11/04 Javascript
jQuery动态生成表格及右键菜单功能示例
2017/01/13 Javascript
AngularJS入门教程一:路由用法初探
2017/05/27 Javascript
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
Vue刷新修改页面中数据的方法
2018/09/16 Javascript
JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解
2018/12/12 Javascript
用VueJS写一个Chrome浏览器插件的实现方法
2019/02/27 Javascript
layer.open的自适应及居中及子页面标题的修改方法
2019/09/05 Javascript
javascript利用canvas实现鼠标拖拽功能
2020/07/23 Javascript
[01:28:31]《加油DOTA》真人秀 第五期
2014/09/01 DOTA
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
python使用urllib2提交http post请求的方法
2015/05/26 Python
tensorflow实现简单的卷积神经网络
2018/05/24 Python
python输入中文的实例方法
2020/09/14 Python
简单了解python关键字global nonlocal区别
2020/09/21 Python
HTML5+CSS3绘制锯齿状的矩形
2016/03/01 HTML / CSS
全球知名旅游社区巴西站点:TripAdvisor巴西
2016/07/21 全球购物
戴森西班牙官网:Dyson西班牙
2020/02/04 全球购物
求职者应聘的自我评价
2013/10/16 职场文书
项目经理岗位职责
2013/11/11 职场文书
安全生产大检查方案
2014/05/07 职场文书
计划生育标语
2014/06/23 职场文书
商铺租房协议书范本
2014/12/04 职场文书
就业意向书范本
2015/05/11 职场文书
西柏坡观后感
2015/06/08 职场文书
党员廉政准则心得体会
2016/01/20 职场文书