蟒蛇与鳄鱼生死大战:java正则表达式(2)
来源:百度文库 编辑:九乡新闻网 时间:2024/10/02 18:50:22
from:http://topic.csdn.net/u/20080627/14/8a91b33a-f35c-4303-85b5-e0a8da462202.html
1.不以某某开头 ,比如不以www开头
public class Test {
public static void main(String[] args) {
String[] strs = {
"abc1232", "wwwadsf",
"awwwfas", "wwadfsf",
"", "ww", " ", "www"
};
String regex = "(?:(?!^www).)*";//regex = "(?!^www).*";貌似也可以
for(String str : strs) {
System.out.printf("%-7s %s%n", str, str.matches(regex));
}
}
}
(?!X) 专业名称为 Negative Lookahead,表示字符间缝隙后面不允许出现的字符,即匹配字符间的缝隙,如果缝隙后的字符不是 X 的话,那这个缝隙就匹配成功。
举个例子,aab 和 aac,现有表达式 aa(?!b) 这时我们能匹配到的字符串是 aac,因为 aa 的后面的缝隙之后不允许出现字符 b,因此只有 aac 进行了匹配。
再来看个示例:
public class Test {
public static void main(String[] args) {
String str = "AQuickBrownFoxJumpsOverTheLazyDog";
String[] strs = str.split("(?
for(String s : strs) {
System.out.println(s);
}
}
}
根据大写字母拆分字符串。当然了,这个使用字符串进行分析同样也能进行拆分,但是使用正则表达式来拆的话更为便捷直观一些。
在进行这种拆分时,由于在拆分后的字符数不能减少,因此只能使用零宽度的lookaround 功能进行匹配,lookaround 包括四个,即:(?=X) (?!X) (?<=X) (?
来看一下这个表达式:(?
前面说到过:
(?!) 表示缝隙后面不允许出现的东西,而
(?
(?=) 表示缝隙后允许出现的东西,
(?<=) 表示缝隙前允许出现的东西。
这个表达式在拆分时,根据零宽度匹配缝隙进行拆分的,这个缝隙必须满足以下条件:
(?
A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog
PS:不加 (?
|A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog
根据 split 的功能,正则表达式处理程序就根据上面的 | 将字符串给拆分开来了。
2. 不区分大小写
不加任何限制的匹配是匹配分大小写的,但是正则表达式中可以进行改变,有两种方式:参数式和内嵌式。
来看个示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String str = "Book";
Pattern pattern = Pattern.compile("book");
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.matches());
}
}
上面的这个表达式 book 是不能匹配字符串 Book 的,这时我们只要给定编译时的参数就可以了:
Pattern pattern = Pattern.compile("book", Pattern.CASE_INSENSITIVE);
Pattern.CASE_INSENSITIVE 这是一个 int 类型的常量,值为 2。表示表达式忽略大小写进行区配。如果我们不采用 Pattern 和 Matcher 两个类来匹配的话,只是使用 String 的 matches 方法的话,我们就不能指定表达式的编译参数了,这时就需要采用内嵌标志表达式了,与 Pattern.CASE_INSENSITIVE,对应的内嵌标志表达式是 (?i),它有四种形式:
1,(?i)
2,(?-i)
3,(?i:X)
4,(?-i:X)
不带有 - 的是开标志,带有 - 的是关标志。
把上面的代码改成这样:
class Test {
public static void main(String[] args) {
String str = "Book";
String regex = "(?i)book";
System.out.println(str.matches(regex));
}
}
我们就达到了同样的效果,当然这样并不是最好的,因为字符串中只有 B 是大写的,我们没有必要把所有的字符都进行不区分大小写匹配,我们可以在打开标志,用 (?i) 的第二种形式马上关掉它:String regex = "(?i)b(?-i)ook";
这样的话,只有 b 是区分大小写了,而 (?-i) 后面的还是得区分大小写匹配的。这样写可能看上去很不顺眼,我们还能使用第 3 种形式直接指定某些字符是不区分大小写的。
String regex = "(?i:b)ook";
这样的表达式与上面的那个在语义上是相同的。就效率上肯定是优于一下子开,一下子关的。可见内嵌标志表达式要比指定编译参数的功能强大许多。
使用建议:如果能确定某些字符的大小写时,尽量使用已确定的字符,对于不确定的可以采用
(?i:X) 的方式指定。因此打开不区分大小写开关时,对匹配的性能是有一定影响的。
思考一下:String regex = "(?i)b(?-i:oo)k"; 这个表达式的意思?
3.多个单元的或操作
| 称为多选结构,用于匹配 | 之中的任何一个,拿你的例子来说明:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String str =
"/n" +
"/n" +
"";
String regex = " ";
//String regex = " ";貌似也可以
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
System.out.println(matcher.group());
}
}
}
注意到其中的 (?:ww|3) 在进行多选匹配时尽量找出多选中的规律,以减少多选的字符,www 和 3w 在最后一个字符可以共用,前面的不一样。
(?: ) 的意思表示组成一组,如果没有 (?: ) 这样的话,表达式就变成了:
String regex = " ";
这样的语义完全变掉了,| 是在一组中进行选择,由于上面的那个表达式中没有组,就把整个表达式作为了一组,使用 | 的话,就进行了整个表达式的多选结构了。这个表达式的意思是:
匹配 ,这样的结果并不是我们所要的。
我们仅仅需要在 ww 和 3 之间进行选择,这时只要把 ww 和 3 放在一组中进行多选择就可以了,变成 (?:ww|3)。
还有,在多选结构中尽量把出现频率高的放在前面,这样可以加快匹配速度。
多选结构的效率在传统型的引擎中是效率低下的,如果是单个字符的选择,比如 a $ & 之中的一个,那就不要使用 (?:a|$|&) 了,可以直接使用字符类 [a$&] 就可以了。
4.解释一下这个正则的意义:String CONDITION = "(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)";
from:http://topic.csdn.net/u/20080716/22/80cdd418-a0e9-4e7e-8435-df6d4bc11c4a.html
要解释这个,得先弄清楚 (?=) 这个表示什么意思。(?=.*[a-z]) 表示当前位置后面必须出现 .*[a-z] 的字符,这个可以理解为必须出现小写字母。
或者可以理解为某一个字符间的缝隙必须满足的条件,这个仅仅作为条件判断并不能匹配任何字
符,因为这属于非捕获组中的环视(lookarround)零宽度匹配。
举个大家常见的例子:
表达式:Win(?=XP)
现有字符串 WinXP 和 WinNT,在应用这个表达式时前者能与之进行匹配,为什么呢?
当匹配器指示到 (?=XP) 时,也就是在 n 字母后面的缝隙,这个缝隙必须满足的条件是:后面的字符必须是 XP,如果是的话,匹配成功,否则匹配失败。由于(?=XP) 是匹配缝隙的,因此并不会把 XP 给匹配输出,而只输出了 Win 因此,这个表达式的语义可以看作是:找到后面为“XP”字符所有的 Win。
假如,我们把表达式写成 Win(?=XP)(?=NT) 这样的话,那么这个语义是:找出后面为“XP”并且为“NT”字符所有的 Win 可以想象,这是个永远无法满足的匹配。(?=XP)(?=NT) 这个表示当前的缝隙必须同时满足的条件。
把这个表达式再改一下,改成 Win(?=.*XP)(?=.*NT) 这个表示 Win 的后面必须出现XP 与 NT,位置和顺序都是无关的(这主要是 .* 的作用)。当然了这个表达式的效率是比较低的,得向后进行两次断言。
如果字符串是 WincbaXPabcNT 这个字符串,当匹配指示器走到 n 后面的缝隙时开始进行向后断言,首先对 .*XP 进行断言,很明显能将 cbaXP 匹配成功,这时第一个断言完成,再对 .*NT 断言,可以看出 cbaXPabcNT 能与其匹配成功,这时第二个断言完成,因此表达式 Win(?=.*XP)(?=.*NT) 能对 WincbaXPabcNT 进行匹配。
同理 WincbaNTabcXP 也是同样的效果。
如果能理解上面的这些,对于 (?=.*[a-z])(?=.*[A-Z])(?=.*\\d) 这个的理应该不会很难吧,这个只不过是必须同时满足三个条件。
这个表达式在开始部分就进行断言,即索引为 0 的地方,也就是第一个字符的前面的缝隙,这个缝隙后面的字符必须满足 .*[a-z] .*[A-Z] .*\\d 三个条件,也就是说必后面必须出现至少一个小写字母、至少一个大写母、至少一个数字。
--------转载
1.不以某某开头 ,比如不以www开头
public class Test {
public static void main(String[] args) {
String[] strs = {
"abc1232", "wwwadsf",
"awwwfas", "wwadfsf",
"", "ww", " ", "www"
};
String regex = "(?:(?!^www).)*";//regex = "(?!^www).*";貌似也可以
for(String str : strs) {
System.out.printf("%-7s %s%n", str, str.matches(regex));
}
}
}
(?!X) 专业名称为 Negative Lookahead,表示字符间缝隙后面不允许出现的字符,即匹配字符间的缝隙,如果缝隙后的字符不是 X 的话,那这个缝隙就匹配成功。
举个例子,aab 和 aac,现有表达式 aa(?!b) 这时我们能匹配到的字符串是 aac,因为 aa 的后面的缝隙之后不允许出现字符 b,因此只有 aac 进行了匹配。
再来看个示例:
public class Test {
public static void main(String[] args) {
String str = "AQuickBrownFoxJumpsOverTheLazyDog";
String[] strs = str.split("(?
for(String s : strs) {
System.out.println(s);
}
}
}
根据大写字母拆分字符串。当然了,这个使用字符串进行分析同样也能进行拆分,但是使用正则表达式来拆的话更为便捷直观一些。
在进行这种拆分时,由于在拆分后的字符数不能减少,因此只能使用零宽度的lookaround 功能进行匹配,lookaround 包括四个,即:(?=X) (?!X) (?<=X) (?
来看一下这个表达式:(?
前面说到过:
(?!) 表示缝隙后面不允许出现的东西,而
(?
(?=) 表示缝隙后允许出现的东西,
(?<=) 表示缝隙前允许出现的东西。
这个表达式在拆分时,根据零宽度匹配缝隙进行拆分的,这个缝隙必须满足以下条件:
(?
A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog
PS:不加 (?
|A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog
根据 split 的功能,正则表达式处理程序就根据上面的 | 将字符串给拆分开来了。
2. 不区分大小写
不加任何限制的匹配是匹配分大小写的,但是正则表达式中可以进行改变,有两种方式:参数式和内嵌式。
来看个示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String str = "Book";
Pattern pattern = Pattern.compile("book");
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.matches());
}
}
上面的这个表达式 book 是不能匹配字符串 Book 的,这时我们只要给定编译时的参数就可以了:
Pattern pattern = Pattern.compile("book", Pattern.CASE_INSENSITIVE);
Pattern.CASE_INSENSITIVE 这是一个 int 类型的常量,值为 2。表示表达式忽略大小写进行区配。如果我们不采用 Pattern 和 Matcher 两个类来匹配的话,只是使用 String 的 matches 方法的话,我们就不能指定表达式的编译参数了,这时就需要采用内嵌标志表达式了,与 Pattern.CASE_INSENSITIVE,对应的内嵌标志表达式是 (?i),它有四种形式:
1,(?i)
2,(?-i)
3,(?i:X)
4,(?-i:X)
不带有 - 的是开标志,带有 - 的是关标志。
把上面的代码改成这样:
class Test {
public static void main(String[] args) {
String str = "Book";
String regex = "(?i)book";
System.out.println(str.matches(regex));
}
}
我们就达到了同样的效果,当然这样并不是最好的,因为字符串中只有 B 是大写的,我们没有必要把所有的字符都进行不区分大小写匹配,我们可以在打开标志,用 (?i) 的第二种形式马上关掉它:String regex = "(?i)b(?-i)ook";
这样的话,只有 b 是区分大小写了,而 (?-i) 后面的还是得区分大小写匹配的。这样写可能看上去很不顺眼,我们还能使用第 3 种形式直接指定某些字符是不区分大小写的。
String regex = "(?i:b)ook";
这样的表达式与上面的那个在语义上是相同的。就效率上肯定是优于一下子开,一下子关的。可见内嵌标志表达式要比指定编译参数的功能强大许多。
使用建议:如果能确定某些字符的大小写时,尽量使用已确定的字符,对于不确定的可以采用
(?i:X) 的方式指定。因此打开不区分大小写开关时,对匹配的性能是有一定影响的。
思考一下:String regex = "(?i)b(?-i:oo)k"; 这个表达式的意思?
3.多个单元的或操作
| 称为多选结构,用于匹配 | 之中的任何一个,拿你的例子来说明:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String str =
"
"
"
String regex = "
//String regex = "
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
System.out.println(matcher.group());
}
}
}
注意到其中的 (?:ww|3) 在进行多选匹配时尽量找出多选中的规律,以减少多选的字符,www 和 3w 在最后一个字符可以共用,前面的不一样。
(?: ) 的意思表示组成一组,如果没有 (?: ) 这样的话,表达式就变成了:
String regex = "
这样的语义完全变掉了,| 是在一组中进行选择,由于上面的那个表达式中没有组,就把整个表达式作为了一组,使用 | 的话,就进行了整个表达式的多选结构了。这个表达式的意思是:
匹配
我们仅仅需要在 ww 和 3 之间进行选择,这时只要把 ww 和 3 放在一组中进行多选择就可以了,变成 (?:ww|3)。
还有,在多选结构中尽量把出现频率高的放在前面,这样可以加快匹配速度。
多选结构的效率在传统型的引擎中是效率低下的,如果是单个字符的选择,比如 a $ & 之中的一个,那就不要使用 (?:a|$|&) 了,可以直接使用字符类 [a$&] 就可以了。
4.解释一下这个正则的意义:String CONDITION = "(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)";
from:http://topic.csdn.net/u/20080716/22/80cdd418-a0e9-4e7e-8435-df6d4bc11c4a.html
要解释这个,得先弄清楚 (?=) 这个表示什么意思。(?=.*[a-z]) 表示当前位置后面必须出现 .*[a-z] 的字符,这个可以理解为必须出现小写字母。
或者可以理解为某一个字符间的缝隙必须满足的条件,这个仅仅作为条件判断并不能匹配任何字
符,因为这属于非捕获组中的环视(lookarround)零宽度匹配。
举个大家常见的例子:
表达式:Win(?=XP)
现有字符串 WinXP 和 WinNT,在应用这个表达式时前者能与之进行匹配,为什么呢?
当匹配器指示到 (?=XP) 时,也就是在 n 字母后面的缝隙,这个缝隙必须满足的条件是:后面的字符必须是 XP,如果是的话,匹配成功,否则匹配失败。由于(?=XP) 是匹配缝隙的,因此并不会把 XP 给匹配输出,而只输出了 Win 因此,这个表达式的语义可以看作是:找到后面为“XP”字符所有的 Win。
假如,我们把表达式写成 Win(?=XP)(?=NT) 这样的话,那么这个语义是:找出后面为“XP”并且为“NT”字符所有的 Win 可以想象,这是个永远无法满足的匹配。(?=XP)(?=NT) 这个表示当前的缝隙必须同时满足的条件。
把这个表达式再改一下,改成 Win(?=.*XP)(?=.*NT) 这个表示 Win 的后面必须出现XP 与 NT,位置和顺序都是无关的(这主要是 .* 的作用)。当然了这个表达式的效率是比较低的,得向后进行两次断言。
如果字符串是 WincbaXPabcNT 这个字符串,当匹配指示器走到 n 后面的缝隙时开始进行向后断言,首先对 .*XP 进行断言,很明显能将 cbaXP 匹配成功,这时第一个断言完成,再对 .*NT 断言,可以看出 cbaXPabcNT 能与其匹配成功,这时第二个断言完成,因此表达式 Win(?=.*XP)(?=.*NT) 能对 WincbaXPabcNT 进行匹配。
同理 WincbaNTabcXP 也是同样的效果。
如果能理解上面的这些,对于 (?=.*[a-z])(?=.*[A-Z])(?=.*\\d) 这个的理应该不会很难吧,这个只不过是必须同时满足三个条件。
这个表达式在开始部分就进行断言,即索引为 0 的地方,也就是第一个字符的前面的缝隙,这个缝隙后面的字符必须满足 .*[a-z] .*[A-Z] .*\\d 三个条件,也就是说必后面必须出现至少一个小写字母、至少一个大写母、至少一个数字。
--------转载
每一种人生都是大家建筑的。
java正则表达式(2)
Java正则表达式入门
JAVA正则表达式
java正则表达式全集12
Java 正则表达式(转载)
正则表达式
java如何利用正则表达式去掉文本中的HTML标签
常用HTML正则表达式
常用正则表达式
正则表达式 - RegexBuddy教程
身份证的正则表达式
常用正则表达式1
正则表达式Sed
常用正则表达式
正则表达式参考文档
Oracle正则表达式规则
深入浅出之正则表达式
C#正则表达式整理备忘
正则表达式30分钟入门教程
ASP.NET 中的正则表达式
正则表达式30分钟入门教程
Python正则表达式操作指南
正则式,正则表达式,多行匹配,不以某某开头,不区分大小写,2个单元的或操作
关于正则表达式、正则文法、NFA、LR(1)