代码之家  ›  专栏  ›  技术社区  ›  dustydojo

在Java中,如何对标记中包含分隔符的字符串进行标记化?

  •  1
  • dustydojo  · 技术社区  · 6 年前

    假设我有字符串:

    String toTokenize = "prop1=value1;prop2=String test='1234';int i=4;;prop3=value3";
    

    我想要代币:

    1. prop1=值1
    2. prop2=管柱测试='1234';int i=4;
    3. prop3=值3

    为了向后兼容,我必须使用分号作为分隔符。我尝试过将代码包装在CDATA中:

    String toTokenize = "prop1=value1;prop2=<![CDATA[String test='1234';int i=4;]]>;prop3=value3";
    

    但我无法找到一个正则表达式来忽略cdata标记中的分号。

    我已尝试转义非分隔符:

    String toTokenize = "prop1=value1;prop2=String test='1234'\\;int i=4\\;;prop3=value3";
    

    但是,移除转义角色的过程中出现了一个丑陋的混乱。

    你有什么建议吗?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Wiktor Stribiżew    6 年前

    您可以匹配 <![CDATA...]]> 或任何字符 ; ,1次或多次,以匹配值。要匹配键,可以使用常规 \w+ 图案:

    (\w+)=((?:<!\[CDATA\[.*?]]>|[^;])+)
    

    请参见 regex demo .

    细节

    • (\w+) -组1:一个或多个单词字符
    • = -a = 签名
    • ((?:<!\[CDATA\[.*?]]>|[^;])+) -第1组:一个或多个序列
      • <!\[CDATA\[.*?]]> -a <![CDATA[...]]> 子字符串
      • | -或
      • [^;] -任何字符,但 ;

    参见a Java demo :

    String rx = "(\\w+)=((?:<!\\[CDATA\\[.*?]]>|[^;])+)";
    String s = "prop1=value1;prop2=<![CDATA[String test='1234';int i=4;]]>;prop3=value3";
    Pattern pattern = Pattern.compile(rx);
    Matcher matcher = pattern.matcher(s);
    while (matcher.find()) {
        System.out.println(matcher.group(1) + " => " + matcher.group(2));
    }
    

    结果:

    prop1 => value1
    prop2 => <![CDATA[String test='1234';int i=4;]]>
    prop3 => value3
    
        2
  •  0
  •   Bentaye    6 年前

    先决条件:

    • 所有代币都以 prop

    • 没有 道具 在文件中,而不是标记的开头

    我会把所有的都替换掉 ;prop 通过 ~prop

    然后字符串变为:

    "prop1=value1~prop2=String test='1234';int i=4~prop3=value3";
    

    然后可以使用 ~ 分隔符