Java正则表达式中的十大问题

来源:互联网 发布:如何检测网络丢包 编辑:程序博客网 时间:2024/06/07 01:02

1.如何从一个字符串中提取数字?

使用正则表达式的一个常见问题是提取所有的数字到整数的数组。在Java中,\ d代表的一系列数字(0-9)。使用预定义的类只要有可能会使你的代码更易于阅读和消除畸形字符类引入的错误。详情请参阅预定义字符类 的更多细节。请注意,第一个反斜杠\的\ D。如果你是一个字符串中使用转义构造,你必须先反斜杠用另一个反斜杠的编译字符串。这就是为什么我们需要使用\\ D。

  1. List<Integer> numbers = new LinkedList<Integer>();
  2. Pattern p = Pattern.compile("\\d+");
  3. Matcher m = p.matcher(str);
  4. while (m.find()) {
  5. numbers.add(Integer.parseInt(m.group()));
  6. }

 2.如何通过换行符分割Java字符串? 

至少有三种不同的方式进入一个新行字符,这取决于您正在使用的操作系统。

在Windows中使用\ r表示CR(回车),在Unix系统中使用\ n表示LF(换行),在Mac OS中使用\ r\ n表示CR + LF,因此,最简单直接的方法是通过换行符来分割字符串

  1. String lines[] = String.split("\\r?\\n");

 但是,如果你不想空行,你可以使用,这也是我最喜欢的方式:

  1. String.split("[\\r\\n]+")

 一个更强大真正独立于系统的方式,如下所示。但要记住,你仍然会得到空行如果有两个换行符并排放置。

  1. String.split(System.getProperty("line.separator"));

 3.Pattern.compile()的重要性

正则表达式,指定为字符串,必须首先被编译成Pattern类的一个实例。 Pattern.compile()方法是创建对象实例的唯一途径。一个典型的调用顺序是这样

  1. Pattern p = Pattern.compile("a*b");
  2. Matcher matcher = p.matcher("aaaaab");
  3. assert matcher.matches() == true;

 从本质上讲,Pattern.compile()是用来将一个正则表达式转移到有限状态机(见编译原理,技术与工具(第二版))。但是,所有参与的状态驻留在匹配器(Matcher)。通过这种方式,Pattern p可以重复使用。和许多匹配器(Matcher)可以共享相同的模式。

  1. Matcher anotherMatcher = p.matcher("aab");
  2. assert anotherMatcher.matches() == true;

 当一个正则表达式只使用一次时,Pattern.matches()方法很方便。这种方法仍然是使用compile()来得到一个Pattern的实例,和一个字符串相匹配。因此,

  1. boolean b = Pattern.matches("a*b", "aaaaab");

 等同于上面的第一次示范代码,虽然对重复匹配它是低效率的,因为它不允许编译Pattern被重复使用。

4.如何摆脱文本的正则表达式? 

一般情况下,正则表达式使用“\”来转义构造,但是这样,Java字符串的转义需要在反斜杠前加上另一个反斜杠,有点痛苦。还有另一种方式为用户传递字符串文字到Pattern,像“$10”。而不是写\\ $5或[$]5,我们可以键入

  1. Pattern.quote("$5");

5.为什么String.split()需要空管分隔符进行转义? 

String.split() 拆分围绕在给定的正则表达式匹配的字符串。 Java表达式支持影响Pattern被匹配的特殊字符,这称为元字符(metcharacter)。 |是用来匹配多个正则表达式中单个正则表达式的元字符。例如,A | B表示A或B。更多详情请参阅交替用竖线或管道符号。因此,要使用|作为字符,你需要在它前面加上\,如\\进行转义|。

  6.我们怎样用Java正则表达式才能匹配anbn(a的n次方b的n次方)? 

这是字符串a连接相等数量的字符串b,如ab,aabb,并aaabbb,由所有非空字符串组成的的语言。这种语言可以被表示为无上下文语法如S→aSb| ab,因此是非规则语言。 

然而,Java正则表达式实现可以识别的不仅仅是正规语言。也就是说,根据形式语言理论定义他们不是“正规”的。采用超前和自我参照的匹配将实现它。在这里,我将给出最终的正则表达式,然后再解释它一点点。对于一个全面的解释,我想请您阅读我们如何匹配^ nb的n次方与Java正则表达式。

  1. Pattern p = Pattern.compile("(?x)(?:a(?= a*(\\1?+b)))+\\1");// true
  2. System.out.println(p.matcher("aaabbb").matches());// false
  3. System.out.println(p.matcher("aaaabbb").matches());// false
  4. System.out.println(p.matcher("aaabbbb").matches());// false
  5. System.out.println(p.matcher("caaabbb").matches());

 而不是解释这个复杂的正则表达式的语法,我宁愿说一点点它是如何操作的。 

1.第一次迭代,它停在第一个a,然后向前看(用a*跳过几步后)是否有a和b。这是通过使用(?:a(?= a*(\\1?+b)))实现的,如果匹配,\ 1,自参考匹配,将匹配内括号中的元素,这是第一次迭代中的单个b。

2.第二次迭代,表达式将停在第二个a,然后向前看(再次跳跃)是否有会是b。但是这一次,\\1+ b实际上相当于bb,所以两个b必须匹配。如果是的话,\1将在第二次迭代后改为bb。 

3.第n次迭代,表达式停在第n个a,看前边是否有n个b。 通过这种方式,该表达式可以计算出a的个数,并匹配后边是否跟着相同数目的b。

7.如何使用单个空格代替有2个或多个空格的字符串和只删除前导空格?

String.replaceAll()用给定的替换字符串替换字符串中与给定的正则表达式匹配的每个子字符串。 “2个或多个空格”,可以通过正则表达式[]+来表示。因此,下面的代码会正常执行。需要注意的是,该解决方案最终不会删除所有前导和尾部空格。如果你想将它们删除,您可以使用在管道(Pipeline)中的String.trim()。

  1. String line = " aa bbbbb ccc d ";// " aa bbbbb ccc d "
  2. System.out.println(line.replaceAll("[\\s]+", " "));

8.如何用正则表达式判断一个数是素数(质数)?

  1. public static void main(String[] args) {
  2. // false
  3. System.out.println(prime(1));
  4. // true
  5. System.out.println(prime(2));
  6. // true
  7. System.out.println(prime(3));
  8. // true
  9. System.out.println(prime(5));
  10. // false
  11. System.out.println(prime(8));
  12. // true
  13. System.out.println(prime(13));
  14. // false
  15. System.out.println(prime(14));
  16. // false
  17. System.out.println(prime(15));}
  18. public static boolean prime(int n) {
  19. return !new String(new char[n]).matches(".?|(..+?)\\1+");}

该函数首先生成n个字符,并试图看是否与字符串匹配 .?|(..+?)\\1 。如果是素数,则表达式将返回false,而非!将反转结果。 

第一部分 .?只是试图确保1不是素数。神奇的部分是反向引用使用的第二部分, (..+?)\\1+先尝试匹配n个字符的长度,然后通过\\1+重复了好几次。

根据定义,一个素数是一个自然数大于1时,有1以外没有正因子和自身。这意味着,如果a = n * m个则不是素数。 n * m可以是进一步解释“重复纳米时代”,而这正是正则表达式的作用:(?+)通过使用匹配n个字符的长度,然后使用\\1+重复m次。因此,如果模式匹配,则这个数不是素数,否则是。提醒非!将反转结果。

9.如何拆分逗号分隔的字符串,但忽略在引号中的逗号? 

你已经达到将正则表达式分解的地步。这能更好,更整洁地写一个简单的拆分器,并能如你所愿的处理特殊情况。 或者,您也可以模仿的有限状态机的操作,通过使用一个switch语句或if-else语句。附件是一个代码片段。

  1. public static void main(String[] args) {
  2. String line = "aaa,bbb,\"c,c\",dd;dd,\"e,e";
  3. List<String> toks = splitComma(line);
  4. for (String t : toks) {
  5. System.out.println("> " + t);
  6. }}
  7. private static List<String> splitComma(String str) {
  8. int start = 0;
  9. List<String> toks = new ArrayList<String>();
  10. boolean withinQuote = false;
  11. for (int end = 0; end < str.length(); end++) {
  12. char c = str.charAt(end);
  13. switch(c) {
  14. case ',':
  15. if (!withinQuote) {
  16. toks.add(str.substring(start, end));
  17. start = end + 1;
  18. }
  19. break;
  20. case '\"':
  21. withinQuote = !withinQuote;
  22. break;
  23. }
  24. }
  25. if (start < str.length()) {
  26. toks.add(str.substring(start));
  27. }
  28. return toks;}

 

  10.如何在Java正则表达式中使用反向引用?

反向引用是Java正则表达式的另一个有用的功能。  

Top 10 Questions for Java Regular Expression

via:http://www.programcreek.com/2013/10/top-10-questions-for-java-regular-expression/


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 工作了和同事在一起住宿舍怎么办 教会的事情商量是起冲突怎么办 转转购买的产品是坏的怎么办 二年级的学生反应太迟钝怎么办? 特别胖的人运动一半体力不支怎么办 怀孕了在胸透门口站了很久怎么办 自己觉的色弱但高考体检正常怎么办 高考体检不合格怎么办会影响录取吗 老婆起诉我离婚我不想离怎么办 中考结束了成绩差的学生怎么办 我儿了眼角模不好了怎么办 打了2次催产针没反应怎么办 高中体检学生隐私被同学看到怎么办 要出去旅游刚好遇上月经期怎么办 兵检的时候还在高中怎么办 人流后带上环20天白带很黄怎么办 武警义务兵训练的时候没合格怎么办 小孩考试考的不好·家长怎么办 怀孕了不小心碰了屁股疼怎么办 新密职教中心开学军训有点慌怎么办 房产证是士兵证办的退伍后怎么办 士兵证办的银行卡退伍了怎么办 看左上牙后引发上颌窦炎怎么办 老板克扣进件加班工资应该怎么办 医生给婴儿按嘴巴碰到喉咙痛怎么办 事故逃逸人死对方要钱太多怎么办 毕业工作未满一年辞职档案怎么办 淘宝上买的东西客服不理怎么办 蚂蚁借呗还款后没显示还款怎么办 王者荣耀什么英雄都打的很烂怎么办 军校参加了政审体检误了怎么办 如果老板搬迁不给工人补偿怎么办 下面的毛很多又掉的厉害怎么办? 想去美国开饭店要怎么办签证 在沙漠中旅游如果车子坏了该怎么办 小磨床平面磨出来很粗怎么办 玩cs鼠标单点总是连点怎么办 论文出现计算上的错误该怎么办 不戴头盔违法扣分怎么办不了缴费 去法国会说英语不会说法语怎么办 企业有很多费用没有正式发票怎么办