所谓环视就是先看,看到了恰当字符序列的之后再尝试匹配。
先了解四个名词:
前瞻 : (?=···)
后顾 :(?<=···)
负前瞻:(?!···)
负后顾:(?<!···)
比如我现在要尝试匹配字符串"我爱"
但是一定要是爱的"编程"
而不是"狗狗"
等其他东西。
这时就用到前瞻的元字符(?=···)
了,前瞻的‘看’虽说也是某种意义上的匹配但是并不会占用字符。
于是我写下了"(?=我爱(编程)|(java))我爱"
,这时候就只能匹配到"我爱编程"
或者我爱java中
的"我爱"
仔细想想其实我想到的是我爱后面紧跟着编程或而java不是别的东西所以这句话也可以写成"我爱(?=(编程)|(java))"
看完了前瞻在来看看后顾,后顾的意思是在‘看’到的后面进行匹配比如下面的代码
String str = "我爱java";
str= str.replaceAll("(?<=我爱)(?=java)",",");
System.out.println(str);//我爱,java
意思是在我爱java中添加","但不用一次匹配所有的然后再更换所有的所以比 str= str.replaceAll("我爱java","我爱,java");
效率要高
因为前瞻和后顾都并不占用字符所以
"(?<=我爱)(?=java)"
和"(?=java)(?<=我爱)"
的意思并没有区别。
至于负前瞻(后顾)的意思就是前面(后面)不是某某的字符串
我们现在可以用它来解决金额问题,为了阅读方便金额中每三个数字之间都有一个,
,但是时从结尾处开始划分。
比如12345678¥
我们想得到的形式是12,345,678¥
。呢那么我们只要看到后面有3的倍数的数字的时候就加一个,
,便可以达成目的。
str="12345678¥".replaceAll("(?<=\\d)(?=(\\d\\d\\d)+(?!\\d))",",");
注意(\\d\\d\\d)+
而非\\d\\d\\d
后者只会在最后三个数字前加上一个,
。
为什么我们这里不用\\D
而一定要用负前瞻的(?!\\d)
呢?
因为(?!\\d)
的意思是匹配不是数字,所以只要不是数字就行。
而\\D
则代表了匹配一个不是数字的字符,这里出现一个字符是必须的。
所以后者无法匹配到12345678
这样的后面什么都没有加的字符串。