• Java里正则表达式(包括一些高级用法)


    有些内容只有在 Java 里面才能使用。 ------原文作者:逗号 (他不高兴发博客)

    ## 字符种类

    部分使用频率几乎为 0 的这里不会提及(比如 x 之流)

    ### 普通

    | | 含义 | 助记 |
    | ---- | ------------------------------------- | ----- |
    | s | 非空白 | space |
    | s | 空白 | |
    | d | 数字 | digit |
    | D | 非数字 | |
    | [] | 自定义字符种类可使用 ^ | && 随意组合 | |

    ### 特别

    | | 含义 | 助记 |
    | ------- | ------------------------------------------------------------ | ---------- |
    | h | 横向字符 | horizontal |
    | h | 非横向字符 | |
    | v | 纵向字符(比如说换行符) | vertical |
    | V | 非纵向字符 | |
    | w | 单词字符(包括 - _) | word |
    | W | 非单词字符 | |
    | p{XXX} | POSIX,这个并不常用,在有些时候会方便,Character 有很多 is开头的方法,将方法名中的`is`替换为`Java`可直接使用进行字符匹配:p{javaLowerCase} | posix |
    | Q | 字符转义开始符 | |
    | E | 字符转义结束符,这两个符号之间的内容全部按照字面量处理,里面是所有字符都不会有什么含义,比如 . 就是 .,s 必须匹配s,而不是匹配空白。 | |

    ## 量词

    | | 含义 | 助记 |
    | ----- | ------------- | ---- |
    | ? | 0个或者1个 | |
    | * | 0个或多个 | |
    | + | 1个或多个 | |
    | {m} | m个 | |
    | {m,n} | 介于m~n个之间 | |

    `?`修饰在量词之后,表尽可能少的匹配!

    ## 边界

    ### 普通

    | | 含义 | 助记 |
    | ---- | ------------ | ---- |
    | ^ | 字符开始位置 | |
    | $ | 字符结束位置 | |

    ### 特别

    | | 含义 | 助记 |
    | ---- | ------------------------------ | ---- |
    |  | 单词边界,单词的最前面和最后面 | |
    | B | 非字符串边界 | |

    下面的内容普通人基本上就已经不管了!

    ## 分组捕获

    正则表达式中,每出现一对括号就是新建了个新的组。比如:`(\w+)|(\d+)`

    正则表达式的组可以用使用索引进行引用,形式为:`$index`

    `$0` 默认指向原来的全部字符

    然后索引递增规律如下:

    `((a)|(bc))`

    `$1` 指向 `((a)|(bc))` 匹配的内容

    `$2` 指向 `(a)` 匹配的内容

    `$3` 指向 `(bc)` 匹配的内容

    然而当正则复杂之后,改动将会对索引有较大影响,也不方便计算索引,此时,你可以为组制定名称:

    比如匹配字符串:`a=123,b=456`中间的键值,使用索引,需要写成:`(\w+)=(\S+)`,然后使用`$1`指向 key,使用 `$2` 指向 value。

    我们可以将正则改为:`(?<key>\w+)=(?<value>\S+)`,上述表达式使用 `?<name>` 的形式在正则中为组定义名称。

    ## 引用分组

    在 Java 中,你可以在两种地方使用引用:

    * 正则表达式中

    匹配 `xxx-xxx` 字符 `-` 两边的内容相同,使用索引引用前面的组(`\index`):

    ```regexp
    (\w+)-\1
    ```

    使用名字引用前面的组:

    ```regexp
    (?<content>\w+)-\k<content>
    ```

    * 在 Java 的字符串替换中

    Markdown 中的字符串转为斜线的html:

    ```java
    "*name*".replaceAll("\*(?<content>\w+)\*", "<em>$1</em>")
    "*name*".replaceAll("\*(?<content>\w+)\*", "<em>${content}</em>")
    ```

    ## 模式

    你可以在构造 `Pattern`时设定模式:

    ```Java
    Pattern.compile("abc", Pattern.CASE_INSENSITIVE)
    ```

    模式可以自行到 `Pattern`下查看,这里只说使用方式,在组开头使用 `?flags:`的方式声明模式,比如:

    匹配单词,不区分大小写

    ```regex
    (?i:\w+)
    ```

    记住`i`(忽略大小写)、`s`(. 匹配全部字符)即可,其他基本不用。

    ## 前瞻后顾

    前瞻后顾,是正则表达式中的高级技巧,主要有5种:

    > 注意:虽然这货也有括号,但是这货只算个条件,并不会捕获任何内容,也不会影响索引

    ### 前瞻

    前瞻中不带`<`,并且只影响前面的表达式,意思就是偷偷往前看一下(这看一下没有限制的,可以看到结尾)。

    * `exp1(?=exp2)`

    寻找后面是 exp2 的 exp1

    * `exp1(?!exp2)`

    ### 后顾

    * `(?<=exp1)exp2`

    匹配 exp1 后面的 exp2,前面没有exp1的内容将被忽略,比如,替换`abcba`替换`c`后面的`b`为 `xxx`,需要写为:

    ```java
    "abcba".replaceAll("(?<=c)b", "xxx")
    ```

    `a`后面的`b`则不受影响。

    > 注意:正则表达式`(?<=c)b`不会匹配字符串`cb`,意思就是:
    >
    > ```java
    > assertFalse("cb".matches("(?<=c)b"));
    > assertFalse("b".matches("(?<=c)b"));
    > assertTrue("cb".matches("c(?<=c)b"));
    > ```

    * `(?<!exp1)exp2`

    后顾中带有 `<` ,并且只影响后面的表达式,也就是说,你如果写成这样:`exp2(?<=exp1)`,是没什么卵用的。

    ## 牛刀小试

    以下所有内容只能使用`String#repalceAll`或者`String#matches`完成。

    ### 手机号遮罩

    将`11`位手机号除前4位之外,其他的使用`*`替换。

    ### 格式化数字

    例如:`1234567890` 使用正则替换之后,变为 `1,234,567,890`。

    ### Trim 字符串

    使用正则去除字符串开始和结束的空白字符。

    ### 去除数字结尾的`0`

    `1234.4500`应该处理为`1234.45`,`1234.00`应该处理为`1234`。

    ### 处理文档

    将字符串的`* 测试 * ** 测试 **`的使用单个`*`包围的内容两边分别加上`<h1>`、`</h1>`,不能影响两个`**`包围的内容。

    ### 测试某个字符串是不是合法的Java标识符

    ### 测试`IPv4`

    已知`IPv4`中每一段的数字需要介于0~255,测试某个字符串是否是合法的`IPv4`表达式。

    ### 去除`//`注释

    已知`Java`中可以使用`//` 进行单行注释,请去除一段代码中的这种注释。

    ### 去除`/* 内容 */`注释

    已知`Java`中可以使用`/* */` 进行多行注释,请去除代码中的这种注释。

  • 相关阅读:
    css中后代、元素、类、id选择器以及行间style优先级的比较
    JS小功能x系列6文字自动滚动
    JS小功能系列7自动打字
    JS小功能系列6折叠
    JS小功能系列5图片左右移动
    JS小功能系列4图片轮播综合数字轮播,顺时针逆时针,自动轮播
    JS小功能系列3时钟
    JS小功能系列2商品计算
    JS小功能系列1换一批
    JS隔行变色,鼠标悬停变色
  • 原文地址:https://www.cnblogs.com/tomcatandjerry/p/13364566.html
Copyright © 2020-2023  润新知