一、正则表达式的元字符
元字符 | 说明 | 备注 |
^ | 代表行的开始 | ^abc匹配以abc为开头的行 |
$ | 代表行的结束 | abc$匹配以abc为结尾的行 |
[字符组] [] |
匹配若干字符之一 |
|
| | 表示或的关系 |
|
. | 匹配任意字符 | |
\< | 单词的起始位置 | \<cat 以cat开始的单词 |
\> | 单词的结束为止 | cat\>以cat结尾的单词 |
\ | 转义字符 | \*表示就是匹配*。不作为元字符使用 |
\b | 单词分界符 | |
\d | 数字[0-9] |
|
\s | 匹配空白 |
|
\w | 匹配包括下划线的任何单词字符 |
|
二、量词
元字符 | 说明 | 备注 |
* | 0-无穷 | a*表示匹配0个到多个a字符 |
? | 0-1 | 可以不出现,也可以出现 |
+ | 1-无穷 | 至少出现一次 |
{min,max} | min-max | 能够出现的容许范围是min-max 例如{3,,6} |
{n} | n | 固定出现的次数 |
{min,} | 至少出现的次数 | |
{0,max} | 至多出现的次数 |
三、反向引用
可以匹配与先前部分匹配的同样的文本。正则表达式可以记忆先前匹配的文本。
例如匹配重复的单词,例如 the the
([a-zA-Z]+)\s\1
当然可以出现多个括号,引用的顺序是以开括号从左向右就行的,例如([a-z]+)([A-Z])\s+\1\2
四、问号关联的元字符
环视结构不匹配字符,匹配特定位置
元字符 | 说明 | 备注 |
(?:xxx) | 分组但是不捕获 | |
(?=xxx) | 肯定顺序环视 | 子表达式可以匹配右侧的文本 |
(?!=xxx) | 否定顺序环视 | 子表示式不能匹配右侧的文本 |
(?<=xxx) | 肯定逆序环视 | 子表达式可以匹配左侧的文本 |
(?<!xxx) | 否定逆序环视 | 子表达式不能匹配左侧的文本 |
五、示例
1、提取javadoc的标签和值
标签都是以@开头的,而且标签的key为字母、数字、下划线、连接符组成。然后是空白。然后是value值
value值得模式为非@符合、非换行符。
public class TagParser { private static final Pattern pattern = Pattern.compile("@([\\w-]+)\\s+([^@\\r\\n]+)"); private List<Pair> tags = new ArrayList<Pair>(); public void parse(String content) { tags.clear(); Matcher matcher = pattern.matcher(content); while (matcher.find()) { Pair p = new Pair(); p.key = matcher.group(1); p.value = matcher.group(2); tags.add(p); } } public List<Pair> getTags() { return Collections.unmodifiableList(this.tags); } public static final class Pair { private String key; private String value; public String getKey() { return key; } public String getValue() { return value; } } }
2、为数字插入逗号分隔符
例如数字123456789可读性比较差,插入逗号123,456,789.
此时需要匹配位置,这个位置的左边存在数字,右边数字的个数是3的倍数。
初始定的正则表达式为:(?<=\d)(?=(\d\d\d)+)。但是运行的时候结果为1,2,3,4,5,6,789。因为右边始终是3的倍数的
修改表达式为:(?<=\d)(?=(?:\d\d\d)+$) 这个位置的左边存在数字,右边数字的个数是3的倍数,然后是结尾。