利用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的类树(支持无限分类)
Oct 09 PHP
一个简单的自动发送邮件系统(二)
Oct 09 PHP
PHP MVC模式在网站架构中的实现分析
Mar 04 PHP
PHP生成随机用户名和密码的实现代码
Feb 27 PHP
利用PHP如何实现Socket服务器
Sep 23 PHP
几个优化WordPress中JavaScript加载体验的插件介绍
Dec 17 PHP
解决Yii2邮件发送结果返回成功,但接收不到邮件的问题
May 23 PHP
PHP编程实现微信企业向用户付款的方法示例
Jul 26 PHP
php支付宝系列之电脑网站支付
May 30 PHP
PHP实现链表的定义与反转功能示例
Jun 09 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
Jun 20 PHP
PHP如何解决微信文章图片防盗链
Dec 09 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编写的抽奖程序中奖概率算法
2015/05/14 PHP
PHP+jQuery翻板抽奖功能实现
2015/10/19 PHP
PHP入门教程之正则表达式基本用法实例详解(正则匹配,搜索,分割等)
2016/09/11 PHP
php基于SQLite实现的分页功能示例
2017/06/21 PHP
php curl获取到json对象并转成数组array的方法
2018/05/31 PHP
关于laravel后台模板laravel-admin select框的使用详解
2019/10/03 PHP
Laravel5.5 动态切换多语言的操作方式
2019/10/25 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
Javascript代码混淆综合解决方案-Javascript在线混淆器
2006/12/18 Javascript
jq选项卡鼠标延迟的插件实例
2013/05/13 Javascript
jquery click([data],fn)使用方法实例介绍
2013/07/08 Javascript
Js获取下拉框选定项的值和文本的实现代码
2014/02/26 Javascript
JavaScript实现鼠标滑过图片变换效果的方法
2015/04/16 Javascript
jscript读写二进制文件的方法
2015/04/22 Javascript
实例讲解Jquery中隐藏hide、显示show、切换toggle的用法
2016/05/13 Javascript
Bootstrap基本插件学习笔记之Popover提示框(19)
2016/12/08 Javascript
详解webpack + vue + node 打造单页面(入门篇)
2017/09/23 Javascript
js使用formData实现批量上传
2020/03/27 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
微信小程序自定义组件传值 页面和组件相互传数据操作示例
2019/05/05 Javascript
微信小程序搜索框样式并实现跳转到搜索页面(小程序搜索功能)
2020/03/10 Javascript
JavaScript内置对象之Array的使用小结
2020/05/12 Javascript
ES2020系列之空值合并运算符 '??'
2020/07/22 Javascript
vue实现移动端input上传视频、音频
2020/08/18 Javascript
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
解决Python下imread,imwrite不支持中文的问题
2018/12/05 Python
python3爬虫获取html内容及各属性值的方法
2018/12/17 Python
浅谈Pandas:Series和DataFrame间的算术元素
2018/12/22 Python
python 三元运算符使用解析
2019/09/16 Python
Python实现鼠标自动在屏幕上随机移动功能
2020/03/14 Python
在keras 中获取张量 tensor 的维度大小实例
2020/06/10 Python
Python虚拟环境的创建和包下载过程分析
2020/06/19 Python
使用css3背景渐变中的透明度来设置不同颜色的背景渐变
2014/03/31 HTML / CSS
新闻学毕业生自荐信
2013/11/15 职场文书
敬老月活动总结
2014/08/28 职场文书
放假通知怎么写
2015/08/18 职场文书