StringUtils的使用以及正则表达式的效率问题


StringUtils的使用以及正则表达式的效率问题

工具类org.apache.commons.lang3.StringUtils是JDK提供的操作String类型数据常用工具类

常用API

  1. public static boolean contains(String str,String searchStr)
    str是原始字符串,searchStr是待搜索的字符串,此方法是检查字符串str中是否包含字符串searchStr,如果str为null,则返回false。
  2. public static boolean containsIgnoreCase(String str,String searchStr)
    在字符串str中搜索字符串searchStr,忽略大小写。如果str为Null,则返回false。
  3. public static boolean isBlank(String str)
    检查一个字符串str是否是空白(whitespace),empty (“”)或者null;
  4. public static boolean isEmpty(String str)
    检查一个字符串str是否是empty (“”) 或 null。

为什么要使用StringUtils

用Stringutil便于后人维护,也更方便一些

正则表达式

Java 正则表达式 | 菜鸟教程

String.split()和StringUtils.split()区别

String.split()会包含空字符串,而且是包含 头部的和中间的, 不包含有效数字后面所有的空字符串.StringUtils.split()会过滤所有的空字符串. 当然空格不会被过滤.StringUtils.split()是把分隔符拆成一个个单独的字符,再用这些字符去把字符串进行分割的。只要匹配到了分隔符中的任意一个字符,就会进行f分割。而string.split()是把分隔符作为一个整体来对字符串进行分割。比如分隔符是;,;,那么在用StringUtils.split()时,只要被分割的字符串里遇到;或,,就会被分割。而在用string.split()时,必须被分割的字符串里遇到;,;时才会被分割。


string.split()的分隔符参数其实是正则表达式,而正则表达式的效率存在问题。

正则表达式的实现方式《参考》

第一种是回溯。也就是遇到字符就比较是不是符合当前的模式或可以套进下一个模式,符合就继续“吃”掉字符,不符合有可能要回溯,将之前的字符吐出来,再喂给下一个模式去尝试。比如一个最简单的例子,模式ab|aa, 输入串"aa" 输入的第一个a符合第一个模式"ab"中的a,但第二个a不符合模式中的b,这时要吐出a来,再去尝试第二个模式aa。(a|aa)*遇到这种模式串下,因为每一个字符输入可以匹配两个方向,可能的分支按指数级别增长,遇到aaaaaaaaab这种时,导致指数级别的状态回溯。

另一种是根据正则的模式串,实时构造一个决定性自动机,也就是创建一个很大的状态迁移表,记录了当遇到什么字符时,从什么状态转到什么状态。one-pass便利目标串,根据状态迁移依次走到最后得到结果:接受还是不接受该串。但构造这个模式串的状态会非常多,构造的时间复杂度也是O(m^2),此后单次匹配的时间复杂度是O(n)。n是目标串的长度,m是模式串的长度。

还有一种叫lazy dfa,在进行过程中构造决定性自动机而不是一次过构造整个模式对应的自动机,并且在过程中对自动机进行缓存,这个会比较快点,但单次匹配的复杂度会比较高,印象中是小o(n*m)以上的。

ok。。 因此在cgi程序里面性能关键的查询用regex,会很容易被dos攻击。


文章作者: RD
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 RD !
评论
评论
  目录