java中带回调函数的字符串替换,类似js中的replace(rgExp,function)

在js中, replace函数的功能很强大,其原型是stringObj.replace(rgExp, replaceText), 而replaceText也可以是返回替换文本的函数。这个功能还是比较好的:
function f2c(s) {  
  var test = /(\d+(\.\d*)?)℉/g;  
  return(s.replace(test,function($0,$1,$2) {  
        return((($1-32) * 5/9) + "℃");  
      }  
    )  
  );  
}  
alert(f2c("Water freezes at 32℉ and boils at 212℉."));
如果在java中怎么写呢? 
java中的replace方法也很强大,只是不支持回调函数,所以就动手写了个简单的替换工具类:
/**
 * @author yeyong
 */
public class StringUtils { // 就把它们放在StringUtils工具类中了

  /**
   * 将String中的所有regex匹配的字串全部替换掉
   * @param string 代替换的字符串
   * @param regex 替换查找的正则表达式
   * @param replacement 替换函数
   * @return
   */
  public static String replaceAll(String string, String regex, ReplaceCallBack replacement) {
    return replaceAll(string, Pattern.compile(regex), replacement);
  }

  /**
   * 将String中的所有pattern匹配的字串替换掉
   * @param string 代替换的字符串
   * @param pattern 替换查找的正则表达式对象
   * @param replacement 替换函数
   * @return
   */
  public static String replaceAll(String string, Pattern pattern, ReplaceCallBack replacement) {
    if (string == null) {
      return null;
    }
    Matcher m = pattern.matcher(string);
    if (m.find()) {
      StringBuffer sb = new StringBuffer();
      int index = 0;
      while (true) {
        m.appendReplacement(sb, replacement.replace(m.group(0), index++, m));
        if (!m.find()) {
          break;
        }
      }
      m.appendTail(sb);
      return sb.toString();
    }
    return string;
  }

  /**
   * 将String中的regex第一次匹配的字串替换掉
   * @param string 代替换的字符串
   * @param regex 替换查找的正则表达式
   * @param replacement 替换函数
   * @return
   */
  public static String replaceFirst(String string, String regex, ReplaceCallBack replacement) {
    return replaceFirst(string, Pattern.compile(regex), replacement);
  }

  /**
   * 将String中的pattern第一次匹配的字串替换掉
   * @param string 代替换的字符串
   * @param pattern 替换查找的正则表达式对象
   * @param replacement 替换函数
   * @return
   */
  public static String replaceFirst(String string, Pattern pattern, ReplaceCallBack replacement) {
    if (string == null) {
      return null;
    }
    Matcher m = pattern.matcher(string);
    StringBuffer sb = new StringBuffer();
    if (m.find()) {
      m.appendReplacement(sb, replacement.replace(m.group(0), 0, m));
    }
    m.appendTail(sb);
    return sb.toString();
  }
}

回调类及其一个抽象类: 

/**
 * 字符串替换的回调接口
 *
 * @author yeyong
 *
 */
public interface ReplaceCallBack {
  /**
   * 将text转化为特定的字串返回
   * @param text 指定的字符串
   * @param index 替换的次序
   * @param matcher Matcher对象
   * @return
   */
  public String replace(String text, int index, Matcher matcher);
}
/**
 * 抽象的字符串替换接口
 * <p>主要是添加了$(group)方法来替代matcher.group(group)
 * @author yeyong
 *
 */
public abstract class AbstractReplaceCallBack implements ReplaceCallBack {
  protected Matcher matcher;

  /*
   * (non-Javadoc)
   * @see utils.ReplaceCallBack#replace(java.lang.String, int, java.util.regex.Matcher)
   */
  final public String replace(String text, int index, Matcher matcher) {
    this.matcher = matcher;
    try {
      return doReplace(text, index, matcher);
    } finally {
      this.matcher = null;
    }
  }

  /**
   * 将text转化为特定的字串返回
   * @param text 指定的字符串
   * @param index 替换的次序
   * @param matcher Matcher对象
   * @return
   */
  public abstract String doReplace(String text, int index, Matcher matcher);

  /**
   * 获得matcher中的组数据
   * <p>等同于matcher.group(group)
   * <p> 该函数只能在{@link #doReplace(String, int, Matcher)} 中调用
   * @param group
   * @return
   */
  protected String $(int group) {
    String data = matcher.group(group);
    return data == null ? "" : data;
  }

}

测试一下: 

String string = "the quick-brown fox jumps over the lazy-dog.";
 String pattern = "\\b(\\w)(\\w*?)\\b";
 // 将每个单词改为首字大写其他字母小写
 System.out.println(StringUtils.replaceAll(string, pattern, 
  new AbstractReplaceCallBack() {
   public String doReplace(String text, int index, Matcher matcher) {
     return $(1).toUpperCase() + $(2).toLowerCase();
   }
 }));
 //输出:The Quick-Brown Fox Jumps Over The Lazy-Dog.

 // 将文本中类似aaa-bbb-ccc的替换为AaaBbbCcc
 string = "the quick-brown fox jumps over the lazy-dog. aaa-bbbb-cccc-ddd";
 pattern = "\\b\\w+(?:-\\w+)+\\b";
 System.out.println(StringUtils.replaceAll(string, pattern, 
   new AbstractReplaceCallBack() {
   private ReplaceCallBack callBack = new AbstractReplaceCallBack() {
     public String doReplace(String text, int index, Matcher matcher) {
       return $(1).toUpperCase() + $(2).toLowerCase();
     }
   };

   public String doReplace(String text, int index, Matcher matcher) {
     return StringUtils.replaceAll(text, "(?:\\b|-)(\\w)(\\w*?)\\b", callBack);
   }
 }));
 // 输出: the QuickBrown fox jumps over the LazyDog. AaaBbbbCcccDdd

 //过滤安全字符... TODO 应提取为一个方法
 final Map<String, String> map = new HashMap<String, String>() {
   private static final long serialVersionUID = 1L;
   {
      put("<", "&lt;");
      put(">", "&gt;");
      put("\"", "&quot;");
      put("'", "&apos;");
   }
 };
 ReplaceCallBack callBack = new ReplaceCallBack() {
   public String replace(String text, int index, Matcher matcher) {
     return map.get(text);
  }
 };
 string = "<html><body>xxxxx 1<4 & 7>5</body></html>";
 System.out.println(StringUtils.replaceAll(string.replace("&", "&amp;"), 
     "[<>\"\']", callBack));
 // 输出: &lt;html&gt;&lt;body&gt;xxxxx 1&lt;4 &amp; 7&gt;5&lt;/body&gt;&lt;/html&gt;

实现上面js例子的替换: 

// 实现上面js例子的替换
  string = "Water freezes at 32℉ and boils at 212℉.";
  System.out.println(StringUtils.replaceAll(string, "(\\d+(\\.\\d*)?)℉", 
    new AbstractReplaceCallBack() {
    public String doReplace(String text, int index, Matcher matcher) {
      return (((Double.parseDouble($(1)) - 32) * 5 / 9) + "℃");
    }
  }));
 // 输出: Water freezes at 0.0℃ and boils at 100.0℃.




转载于:https://my.oschina.net/jsan/blog/185189

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值