利用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页面缓存ob系列函数介绍
Oct 18 PHP
php中删除、清空session的方式总结
Oct 09 PHP
thinkPHP的表达式查询用法详解
Sep 14 PHP
PHP常用算法和数据结构示例(必看篇)
Mar 15 PHP
PHP获取文件扩展名的方法实例总结
Jun 10 PHP
实例讲解YII2中多表关联的使用方法
Jul 21 PHP
PHP 实现公历日期与农历日期的互转换
Sep 13 PHP
php中上传文件的的解决方案
Sep 25 PHP
CI框架网页缓存简单用法分析
Dec 26 PHP
php创建类并调用的实例方法
Sep 25 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
Oct 11 PHP
在laravel中实现ORM模型使用第二个数据库设置
Oct 24 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
索尼SONY ICF-7600A(W)电路分析
2021/03/01 无线电
php中3种方法统计字符串中每种字符的个数并排序
2012/08/27 PHP
twig里使用js变量的方法
2016/02/05 PHP
Zend Framework实现留言本分页功能(附demo源码下载)
2016/03/22 PHP
Windows2003下php5.4安装配置教程(IIS)
2016/06/30 PHP
Yii框架弹出窗口组件CJuiDialog用法分析
2017/01/07 PHP
javascript 异步页面查询实现代码(asp.net)
2010/05/26 Javascript
基于jQuery实现模拟页面加载进度条
2013/04/01 Javascript
js实现的早期滑动门菜单效果代码
2015/08/27 Javascript
原生js开发的日历插件
2017/02/04 Javascript
Ajax异步获取html数据中包含js方法无效的解决方法
2017/02/20 Javascript
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
让div运动起来 js实现缓动效果
2017/07/06 Javascript
微信小程序将字符串生成二维码图片的操作方法
2018/07/17 Javascript
详解vue axios用post提交的数据格式
2018/08/07 Javascript
详解微信小程序调用支付接口支付
2019/04/28 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
javascript使用Blob对象实现的下载文件操作示例
2020/04/18 Javascript
启动targetcli时遇到错误解决办法
2017/10/26 Python
pandas的object对象转时间对象的方法
2018/04/11 Python
将python代码和注释分离的方法
2018/04/21 Python
详解django中使用定时任务的方法
2018/09/27 Python
树莓派用python中的OpenCV输出USB摄像头画面
2019/06/22 Python
python实现输入三角形边长自动作图求面积案例
2020/04/12 Python
Virtualenv 搭建 Py项目运行环境的教程详解
2020/06/22 Python
pytorch判断是否cuda 判断变量类型方式
2020/06/23 Python
CSS3轻松实现清新 Loading 效果的简单实例
2016/06/06 HTML / CSS
英国最大的线上保健品零售商之一:Vitamin Planet
2016/12/01 全球购物
您的健身减肥和健康饮食专家:vitafy
2017/06/06 全球购物
美国优质宠物用品购买网站:Muttropolis
2020/02/17 全球购物
高中军训感言200字
2014/02/23 职场文书
白血病募捐倡议书
2014/05/14 职场文书
禁毒主题班会教案
2015/08/14 职场文书
优秀创业计划书分享
2019/07/19 职场文书
世界各国短波电台对东亚播送时间频率表(SW)
2021/06/28 无线电
Python 游戏大作炫酷机甲闯关游戏爆肝数千行代码实现案例进阶
2021/10/16 Python