java正则表达式十大问题及答案

这篇文章总结了有关Java正则表达式的主要问题。希望可以给同学们带来java学习路上的成长!

java正则表达式十大问题及答案

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

使用正则表达式的一个常见问题是将所有数字提取到整数数组中。

在Java中,\d表示数字范围(0-9)。尽可能使用预定义的类将使您的代码更易于阅读,并消除了格式错误的字符类所引起的错误。请参阅预定义字符类以获取更多详细信息。请注意,第一个反斜杠\在\d。如果在字符串文字中使用转义的构造,则必须在反斜杠之前加上另一个反斜杠,才能编译字符串。这就是为什么我们需要使用\\d。

列表<整数>数字= 新的LinkedList <整数> ();

模式p =模式。编译(“ \\d +” );

匹配器m = p。匹配器( str ); (米。找到()) {

号码。添加(整数。parseInt函数(米。组())); }

2.如何用换行符分割Java String?

根据所使用的操作系统,至少有三种输入换行符的方法。

\ r表示CR(回车),在Unix中使用

\ n表示LF(换行),在Mac OS中使用

\ r \ n表示Windows中使用的CR + LF

因此,用换行符分割字符串的最直接方法是

字符串行[ ] = 字符串。分割(“ \\r?\\n” );

但是,如果您不希望出现空行,则可以使用,这也是我最喜欢的方式:

字符串。分割(“ [ \\r \\n] +” )

一种更可靠的方法(实际上与系统无关)如下。但是请记住,如果两个换行符并排放置,您仍然会得到空行。

字符串。分裂(系统。的getProperty (“line.separator” )) ;

3. Pattern.compile()的重要性

必须先将指定为字符串的正则表达式编译为Pattern类的实例。图案。compile()方法是创建对象实例的唯一方法。因此,典型的调用顺序为

模式p =模式。编译(“ a * b” );

匹配器匹配器= p。匹配器(“ aaaaab” );断言匹配器。匹配() == true ;

本质上是Pattern。compile()用于将正则表达式转换为有限状态机(请参见《编译器:原理,技巧和工具》(第二版))。但是执行比赛所涉及的所有状态都位于比赛者中。通过这种方式,模式p可以被重用。而且许多匹配器可以共享相同的模式。

匹配器anotherMatcher = p。匹配器(“ aab” );声明anotherMatcher。匹配() == true ;

模式。当只使用一次正则表达式时,matches()方法被定义为一种便利。该方法仍然使用compile()隐式获取Pattern的实例,并匹配字符串。因此,

布尔值b =模式。匹配项(“ a * b”,“ aaaaab” );

等效于上面的第一个代码,尽管对于重复匹配它效率较低,因为它不允许重新使用已编译的模式。

4.如何转义文本以进行正则表达式?

通常,正则表达式使用“ \”转义结构,但是要在反斜杠之前加上另一个反斜杠以使Java字符串得以编译是很痛苦的。用户还有另一种方式将字符串Literals传递给Pattern,例如“ $ 5”。不用写\\$5or [$]5,我们可以输入

图案。quote (“ $ 5” );

5.为什么String.split()需要使用管道定界符进行转义?

字符串。split()在给定正则表达式的匹配项周围拆分字符串。Java表达式支持影响模式匹配方式的特殊字符,称为metacharacter。|是一个元字符,用于匹配多个可能的正则表达式中的单个正则表达式。例如,A|B表示A或B。有关更多详细信息,请参考“竖线或管道符号交替显示”。因此,要|用作文字,您需要通过\在其前面添加来对其进行转义,例如\\|。

6.我们如何将a n b n与Java正则表达式匹配?

这是由一定数量的所有非空字符串的语言a的后面是数量相等b的,如ab,aabb和aaabbb。该语言可以显示为无上下文语法S→aSb | ab,因此是非常规语言。

但是,Java regex实现不仅仅可以识别常规语言。也就是说,根据形式语言理论的定义,它们不是“正常的”。使用前瞻匹配自引用匹配即可实现。在这里,我将首先给出最终的正则表达式,然后再进行一些解释。要获得全面的解释,请参阅“ 如何将a ^ nb ^ n与Java regex匹配”。

模式p =模式。编译(“(?x)(?: a(?= a *(\\1?+ b)))+ \\1” );// true 系统。出来。的println (第匹配(“AAABBB” )。 匹配()); //错误的System。出来。的println (第匹配(“aaaabbb” )。 匹配()); //错误的System。出来。的println (第匹配(“aaabbbb” )。 匹配()); //错误的System。出来。的println (第匹配(“caaabbb” )。 匹配());

与其解释这个复杂的正则表达式的语法,不如说它是如何工作的。

1. 在第一次迭代中,它在第一次停止,a然后向前看(a使用跳过一些s 之后a*)是否存在b。这是通过使用实现的(?:a(?= a*(\\1?+b)))。如果匹配,\1则自引用匹配将匹配内部括号内的元素,该元素b在第一次迭代中是一个。

2. 在第二次迭代中,表达式将在第二次停止a,然后向前看(再次跳过as)以查看是否会有b。但是这一次\\1+b实际上等于bb,因此b必须匹配两个。如果是这样,\1将更改为bb第二次迭代后。

3. 在Ñ次迭代中,表达停止在Ñ个a,看看是否有Ñ b š前方。

通过这种方式,表达式可以计算as 的数量,并且如果bs 的数量a相同则匹配。

7.如何用字符串中的单个空格替换2个或更多空格并仅删除前导空格?

字符串。replaceAll()使用给定的替换项替换与给定的正则表达式匹配的每个子字符串。“ 2个或更多空格”可以用正则表达式表示[ ]+。因此,以下代码将起作用。请注意,该解决方案最终不会删除所有前导和尾随空格。如果要删除它们,可以使用String。trim()在管道中。

字符串行= “ aa bbbbb ccc d” ; //“ aa bbbbb ccc d” 系统。出来。的println (线。的replaceAll (“[ \\S] +” , “” )) ;

8.如何确定正则表达式是否为质数?

public static voidmain (String [ ] args ) {

//否

系统。出来。println (素数(1 ));

// true

系统。出来。println (素数(2 ));

// true

系统。出来。println (素数(3 ));

// true

系统。出来。println (素数(5 ));

//错误的

System。出来。println (素数(8 ));

// true

系统。出来。println (素数(13 ));

//错误的

System。出来。println (素数(14 ));

//错误的

System。出来。println (素数(15 )); }

公共静态布尔素数(intn ) {

返回new String (new char [ n ] )。匹配(“。?|(.. +?)\\1+” ); }

该函数首先生成n个字符,然后尝试查看该字符串是否匹配.?|(..+?)\\1+。如果为质数,则表达式将返回false,并将返回!结果。

第一部分.?只是试图确保1不是底漆。魔术部分是使用反向引用的第二部分。(..+?)\\1+首先尝试匹配n个字符的长度,然后按重复几次\\1+。

根据定义,素数是大于1的自然数,除1及其本身外,没有其他除数。这意味着如果a = n * m,则a不是质数。n * m个可进一步解释“重复Ñ 米倍”,并且这正是正则表达式的作用:匹配Ñ字符的长度,通过使用(..+?),然后重复其中号通过使用倍\\1+。因此,如果模式匹配,则数字不是质数,否则为质数。提醒您,!结果会相反。

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

您已经到了正则表达式崩溃的地步。编写一个简单的分割器更好,更简洁,并根据需要处理特殊情况。

或者,您可以使用switch语句或if-else来模拟有限状态机的操作。随附的是一段代码。

public static voidmain (String [ ] args ) {

字符串 line = “ aaa,bbb,\”c,c \“,dd; dd,\”e,e“ ;

List < String > toks = splitComma ( line );

for (字符串吨: toks ) {

系统。出来。的println (“>” +吨);

}}

私有静态列表< String > splitComma (String str ) {

intstart = 0 ;

List < String > toks = newArrayList < String > ();

booleaninsideQuote = false ;

INT端= 0 ;端<海峡长度();端++) {

charc = str。charAt ( end );

开关( Ç ) {

情况下'' :

如果(! withinQuote ) {

toks。添加(字符串子串(开始,结束));

开始=结束+ 1 ;

}

打破;

大小写' \“' :

insideQuote = !insideQuote ;

休息;

}

}

如果(开始<海峡长度()) {

toks。添加(海峡子串(开始));

}

返回toks ; }

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

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