import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 类名: MyStringUtil
* 描述:
* 日期: 2021/7/28-13:52
*
* @author
*/
public class MyStringUtil {
public static void main(String[] args) {
System.out.println(splitJoinEnhanceSimpleStr("223456789011人是环境的产物,处境的变化将导致我们心态的变化", 4));
// System.out.println(splitJoinEnhanceFinalStr("223456789012", 3));
// String kouLing = "8✔KfdxXPJ0bUX₤ https://m.tb.cn/h.faIoucS?sm=701e65 上手淘搜索“微淘官网”,淘你喜欢,一搜即得";
/* String kouLing = "5.0\uD83D\uDD109QnGXPJ8o6X£ https://m.tb.cn/h.4AwpTkO?sm=1b5748 短袖很好,没有色差,穿上舒服合身,喜欢的可以下单购买了";
// System.out.println(kouLing.replaceAll("[\\u0080-\\uFFFF]", "").replaceAll("\\b", "¥"));
Pattern compile2 = Pattern.compile("\\w{5,}(?=[\\u0080-\\uFFFF])");
Matcher matcher2 = compile2.matcher(null);
if(matcher2.find()){
System.out.println(matcher2.group().replaceAll("\\b", "¥"));
}*/
}
//(\d{3})+(?!\d) 匹配每3个为一组,后面不是数字的那一串数字
//如果是223,456,789,10 不行,因为分组连串后,9后面是数字
//那么有没有一种组合,能够匹配呢?
//这就要说到正则的回溯作用,先从前往后找,没找到再从后往前找
//深入研究我们发现0后面没有数字,从0开始往前找,大概率就能找到
/**
* 千分位替换:从右往左,每隔n位添加逗号
*
* @param oldStr
* @param width
* @return
*/
public static String micrometerStr(String oldStr, Integer width) {
Objects.requireNonNull(oldStr, "oldStr不能为空!");
if (width >= oldStr.length()) return oldStr;
String regex = String.format("\\B(?=(\\d{%s})+(?!\\d))", width);
return oldStr.replaceAll(regex, ",");
}
/**
* 初版
* 从左到右,每隔n位数字为一组,用逗号分隔
* {@link #splitJoinEnhanceStr(String, Integer)}
* @param oldStr
* @param width n
* @return
*/
public static String splitJoinStr(String oldStr, Integer width) {
Objects.requireNonNull(oldStr, "oldStr不能为空!");
if (width >= oldStr.length()) {
return oldStr;
}
String regex = String.format("(\\d{%s})", width);
Pattern compile1 = Pattern.compile(regex);
Matcher matcher1 = compile1.matcher(oldStr);
List<String> list = new ArrayList<>();
int index = 0;
while (matcher1.find()) {
index = matcher1.end();
list.add(matcher1.group());
}
String join = String.join(",", list);
if (index != 0 && oldStr.length() != index) {
join = String.format("%s,%s", join, oldStr.substring(index));
}
return join;
}
/**
* 增强版
* 从左到右,每隔n位数字为一组,用逗号分隔
* 只用到了匹配之后再替换
*
* @param oldStr
* @param width 数字n
* @return oldStr 替换后的oldStr
*/
public static String splitJoinEnhanceStr(String oldStr, Integer width) {
Objects.requireNonNull(oldStr, "oldStr不能为空!");
if (width >= oldStr.length()) {
return oldStr;
}
String regex = String.format("(\\d{%s})", width);
Matcher matcher = Pattern.compile(regex).matcher(oldStr);
while (matcher.find()) {
oldStr = oldStr.replace(matcher.group(), String.format("%s,", matcher.group()));
}
return oldStr.charAt(oldStr.length() - 1) == ',' ? oldStr.substring(0, oldStr.length() - 2) : oldStr;
}
/**
* 增强简单版:
* 从左到右,每隔n位数字为一组,用逗号分隔
* 直接匹配目标位置,将匹配的位置替换成逗号
* \B非单词边界,\D非数字,【(?<=xxx) 在...前面,不捕获组,该表达式不支持*和+符号 】
* 匹配【前面是每隔n位数字为一组,可以有多组数字】的那个位置
* 类似于定语从句,放于整个句子中去思考
* {@link #splitJoinEnhanceFinalStr(String, Integer)}
* @param oldStr
* @param width 数字n
* @return 替换后的字符串
*/
//(?<=\D+(\d{3})+|^(\d{3})+)\B
public static String splitJoinEnhanceSimpleStr(String oldStr, Integer width) {
Objects.requireNonNull(oldStr, "oldStr不能为空!");
if (width >= oldStr.length()) return oldStr;
//(?<=xxx) 在...前面,不捕获组,该表达式不支持*和+符号
String regex = String.format("(?<=\\D{1,10000}(\\d{3}){1,10000}|^(\\d{3}){1,10000})\\B", width);
String result = oldStr.replaceAll(regex, ",");
return result;
}
/**
* 增强最终版
* 从左到右,每隔n位数字为一组,用逗号分隔
* 只用到了匹配之后再替换,$0....$9 表示第n组
* 匹配到目标字符串后,将目标字符串替换成目标字符串加逗号
*
* @param oldStr
* @param width 数字n
* @return 替换后的字符串
*/
public static String splitJoinEnhanceFinalStr(String oldStr, Integer width) {
Objects.requireNonNull(oldStr, "oldStr不能为空!");
if (width >= oldStr.length()) return oldStr;
String regex = String.format("(\\d{%s})", width);
String result = oldStr.replaceAll(regex, "$0,");
return result.charAt(result.length() - 1) == ',' ? result.substring(0, result.length() - 2) : result;
}
/**
* @param oldStr 要填充的字符串
* @param length 填充后整个字符串的长度:如32位,不足填充0
* @param fillStr 要使用填充的字符串
* @param isRight 是否填充在右边
* @return String
*/
public static String fillStr(String oldStr, Integer length, String fillStr, boolean isRight) {
Objects.requireNonNull(oldStr, "oldStr不能为空!");
//构造 %指定数字s
String format = String.format(isRight ? "%%-%ds" : "%%%ds", length);
// %[argument_index$][flags][width][.precision][t]conversion
// %(\d+\$)?([-#+ 0,(\<]*)?(\d+)?(\.\d+)?([tT])?([a-zA-Z%])
//开始真正的填充,【默认不足位数,左填充空格】
format = String.format(format, oldStr);
// System.out.println(format);
String newStr = format.replace(" ", fillStr);
return newStr;
}
/**
* 描述:用于给集合用指定的分隔符串联起来,并指定前后缀
*
* @param delimiter 分隔符
* @param elements 可迭代的数据结构
* @return
*/
public static String myJoin(CharSequence delimiter,
Iterable<? extends CharSequence> elements) {
return myJoin(delimiter, elements, null, null);
}
/**
* 描述:用于给集合用指定的分隔符串联起来,并指定前后缀
*
* @param delimiter 分隔符
* @param elements 可迭代的数据结构
* @param prefix 前缀
* @param suffix 后缀
* @return
*/
public static String myJoin(CharSequence delimiter,
Iterable<? extends CharSequence> elements,
CharSequence prefix,
CharSequence suffix) {
Objects.requireNonNull(delimiter, "delimiter分隔符不能为空!");
Objects.requireNonNull(elements, "elements不能为空!");
prefix = prefix == null ? "" : prefix;
suffix = suffix == null ? "" : suffix;
//StringJoiner等价于StringBuilder
//可是这样和String.format("【%s】",args)的区别是:String.format不仅仅可以加前缀,各种各样的都可以格式化
StringJoiner joiner = new StringJoiner(delimiter, prefix, suffix);
for (CharSequence cs : elements) {
joiner.add(cs);
}
return joiner.toString();
}
}
我的String工具类
最新推荐文章于 2022-04-25 11:10:12 发布