首頁 > 軟體

Java正規表示式匹配字串並提取中間值的方法範例

2022-06-17 18:03:01

前言

有時候正規表示式不只是匹配一下什麼數位/郵箱/身份證/日期等等,還需要匹配某一段文字,並按照既定格式提取其中的某些值.

場景一:提取SAML2報文

SAML2報文內容如下,從中提取對應的attribute name和value.

<saml:AttributeStatement>
    <saml:Attribute Name="mail">
        <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">zhengkai.blog.csdn.net</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="cn">
        <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">amAdmin</saml:AttributeValue>
    </saml:Attribute>
</saml:AttributeStatement>

show time

public static void main(String[] args) {
        String content = "";
        content = "<saml:AttributeStatement>";
        content += "    <saml:Attribute Name="mail">";
        content += "        <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">zhengkai.blog.csdn.net</saml:AttributeValue>";
        content += "    </saml:Attribute>";
        content += "    <saml:Attribute Name="cn">";
        content += "        <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">amAdmin</saml:AttributeValue>";
        content += "    </saml:Attribute>";
        content += "</saml:AttributeStatement>";
        String pattern = "\<saml\:Attribute Name=\"(?<scope>.*?)\"\>[\s\S]*?\<saml\:AttributeValue[\s\S]*?\>(?<value>.*?)\<\/saml\:AttributeValue\>[\s\S]*?\<\/saml\:Attribute\>";
        Pattern r = Pattern.compile(pattern);
        Matcher matcher = r.matcher(saml2attributeString);
        while (matcher.find()){
            String attributeName = matcher.group("scope");
            String attributeValue = matcher.group("value");
            System.out.println("attributeName->"+attributeName +",attributeValue->"+attributeValue );
        }
    }

控制檯輸出

$ attributeName->mail,attributeValue->zhengkai.blog.csdn.net
$ vattributeName->cn,attributeValue->amAdmin

解析

\<saml\:Attribute Name=\"(?<scope>.*?)\"\>[\s\S]*?\<saml\:AttributeValue[\s\S]*?\>(?<value>.*?)\<\/saml\:AttributeValue\>[\s\S]*?\<\/saml\:Attribute\>
  1. (?<scope>.*?)是用於標識scope的方式,表示夾在中間的字串都叫scope,可以通過matcher.group("scope")提取。
  2. 所有非正則的符號都需要跳脫,所以你會看到很多\<或者換\"之類的\
  3. [\s\S]*? 是用來匹配任意字元,表示在前後有界定的情況下(例如夾在<xxx></xxx>中間的字串),可以忽略那些不規則字串的匹配。

場景2:提取sql中的表名和欄位

來自github網友@ydq 給SpringBootCodeGenerator貢獻的正規表示式,非常不錯,值得深刻學習.

    //匹配整個ddl,將ddl分為表名,列sql部分,表註釋
    private static final Pattern DDL_PATTERN = Pattern.compile("\s*create\s+table\s+(?<tableName>\S+)[^\(]*\((?<columnsSQL>[\s\S]+)\)[^\)]+?(comment\s*(=|on\s+table)\s*'(?<tableComment>.*?)'\s*;?)?$", Pattern.CASE_INSENSITIVE);
    //匹配列sql部分,分別解析每一列的列名 型別 和列註釋
    private static final Pattern COL_PATTERN = Pattern.compile("\s*(?<fieldName>\S+)\s+(?<fieldType>\w+)\s*(?:\([\s\d,]+\))?((?!comment).)*(comment\s*'(?<fieldComment>.*?)')?\s*(,|$)", Pattern.CASE_INSENSITIVE);

    public static void parse(String sql){
        Matcher matcher = DDL_PATTERN.matcher(sql);
        if (matcher.find()){
            String tableName = matcher.group("tableName");
            String tableComment = matcher.group("tableComment");
            System.out.println(tableName + "tt" + tableComment);
            System.out.println("==========");
            String columnsSQL = matcher.group("columnsSQL");
            if (columnsSQL != null && columnsSQL.length() > 0){
                Matcher colMatcher = COL_PATTERN.matcher(columnsSQL);
                while (colMatcher.find()){
                    String fieldName = colMatcher.group("fieldName");
                    String fieldType = colMatcher.group("fieldType");
                    String fieldComment = colMatcher.group("fieldComment");
                    if (!"key".equalsIgnoreCase(fieldType)){
                        System.out.println(fieldName + "tt" + fieldType + "tt" + fieldComment);
                    }
                }
            }
        }
    }

    public static void main(String[] args){
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        parse("CREATE TABLE `userinfo` (n" +
                "  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者ID',n" +
                "  `username` varchar(255) NOT NULL COMMENT '使用者名稱',n" +
                "  `addtime` datetime NOT NULL COMMENT '建立時間',n" +
                "  PRIMARY KEY (`user_id`)n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者資訊'");
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        parse("CREATE TABLE `USER` (n" +
                "`ID` varchar(32) PRIMARY KEY COMMENT '主鍵',n" +
                "`password` varchar(32) NOT NULL COMMENT '密碼',n" +
                "`username` varchar(32) NOT NULL COMMENT '使用者'n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        parse("CREATE TABLE `tb_amount` (n" +
                "`ID` int(10) NOT NULL AUTO_INCREMENT,n" +
                "`PRODUCT_CODE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '產品程式碼',n" +
                "`GENDER` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '性別(male,female)',n" +
                "`MIN_INSURED_AGE` int(3) NULL DEFAULT NULL COMMENT '最小投保年齡',n" +
                "`MAX_INSURED_AGE` int(3) NULL DEFAULT NULL COMMENT '最大投保年齡',n" +
                "`AMOUNT` double(10, 2) NULL DEFAULT NULL COMMENT '基本保額',n" +
                "`PREMIUM_RATE` double(10, 2) NULL DEFAULT NULL COMMENT '基本保費',n" +
                "`YEAR_NUM` int(3) NULL DEFAULT NULL COMMENT '繳費年限',n" +
                "`PREMIUM_TYPE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '費率型別',n" +
                "`INSURANCE_PERIOD` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '保險期間(30年,60年)',n" +
                "`INSURANCE_PERIOD_TYPE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '保險期間型別(如定期年0,定期歲1,終身2,以後終身對應值:200)',n" +
                "`PAY_MODE` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '交費方式',n" +
                "PRIMARY KEY (`ID`) USING BTREEn" +
                ") ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;");
    }

控制檯輸出內容:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
`userinfo`        使用者資訊
==========
`user_id`        int        使用者ID
`username`        varchar        使用者名稱
`addtime`        datetime        建立時間
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
`USER`        null
==========
`ID`        varchar        主鍵
`password`        varchar        密碼
`username`        varchar        使用者
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
`tb_amount`        null
==========
`ID`        int        null
`PRODUCT_CODE`        varchar        產品程式碼
`GENDER`        varchar        性別(male,female)
`MIN_INSURED_AGE`        int        最小投保年齡
`MAX_INSURED_AGE`        int        最大投保年齡
`AMOUNT`        double        基本保額
`PREMIUM_RATE`        double        基本保費
`YEAR_NUM`        int        繳費年限
`PREMIUM_TYPE`        varchar        費率型別
`INSURANCE_PERIOD`        varchar        保險期間(30年,60年)
`INSURANCE_PERIOD_TYPE`        varchar        保險期間型別(如定期年0,定期歲1,終身2,以後終身對應值:200)
`PAY_MODE`        varchar        交費方式

總結

到此這篇關於Java正規表示式匹配字串並提取中間值的文章就介紹到這了,更多相關Java正則匹配字串內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com