【问题标题】:Split String While Ignoring Escaped Character忽略转义字符时拆分字符串
【发布时间】:2015-03-01 03:40:47
【问题描述】:

我想沿空格分割一个字符串,如果它们包含在单引号内,则忽略空格,如果它们被转义(即 \' ),则忽略单引号 我从another question 完成了以下工作。

    String s = "Some message I want to split 'but keeping this a\'s a single string' Voila!";
    for (String a : s.split(" (?=([^\']*\'[^\"]*\')*[^\']*$)")) {
        System.out.println(a);
    }

上面代码的输出是

Some
message
I
want
to
split
'but
keeping
this
'a's a single string'
Voila!

但是,如果单引号被转义( \' ),我需要忽略它们,而上面没有这样做。此外,我需要删除第一个和最后一个单引号和正斜杠,当且仅当它(正斜杠)正在转义单引号('this is a \'string' 将变为 this is a 'string)。我不知道如何使用正则表达式。我将如何做到这一点?

【问题讨论】:

    标签: java regex string


    【解决方案1】:

    您需要使用否定的lookbehind来处理转义的单引号:

    String str = 
            "Some message I want to split 'but keeping this a\\'s a single string' Voila!";
    
    String[] toks = str.split( " +(?=((.*?(?<!\\\\)'){2})*[^']*$)" );
    for (String tok: toks)
        System.out.printf("<%s>%n", tok);
    

    输出:

    <Some>
    <message>
    <I>
    <want>
    <to>
    <split>
    <'but keeping this a\'s a single string'>
    <Voila!>
    

    PS:正如您所指出的,转义单引号需要在String 赋值中输入为\\',否则它将被视为普通'

    【讨论】:

    • 为了让事情更简单,我决定使用字符串“A message '和嵌入的消息!' ”。使用您的模式,我收到字符串 A message 'with an embed\'ded message!'如何删除开头和结尾的单引号,但以用单引号替换“ \' ”的方式进行操作?
    • 编辑我上面的评论。字符串是Amessage'with an embedded message!'对不起,我还是不习惯SE Markdown
    • 同样的代码也适用于"A message 'with an embedded message!'"
    • 我如何删除引号?我不想使用 replace 方法,因为它可以替换内部引号。还有另一个编辑。最后,你的模式的输出返回Amessage'with an embed\'ded message!'。因此,我将如何将'with an embed\'ded message!' 转换为with an embed'ded message!
    • 但请理解,按空格分割不同于从输出中删除引号。最好根据您的问题将其按空格分隔,如果需要,请替换引号。另一种方法是使用 Pattern Matcher 等并提取你想要的。
    【解决方案2】:

    或者你可以使用这个模式来捕捉你想要的东西

    ('(?:[^']|(?!<\\\\)')*'|\S+)  
    

    Demo

    【讨论】:

      【解决方案3】:

      真的想多了这个。

      这应该可以工作,最好的部分是它根本不使用环视(所以它几乎可以在任何正则表达式实现中工作,最著名的是 javascript)

      ('[^']*?(?:\\'[^']*?)*'|[^\s]+)
      

      不要使用拆分,而是使用匹配来构建具有此正则表达式的数组。

      我的目标是

      • 它可以区分转义撇号和不转义撇号(当然)
      • 速度很快。我之前写的这个庞然大物实际上花了时间
      • 它适用于多个子引号,这里的很多建议都没有。

      Demo

      • 测试字符串:区分“单引号的双重用途”作为“引号标记”(如“)和“牵引标记”。

        如果你问作者并且他以第三人称说话,他会说“CFQueryParam 的例子是人为的,他知道这一点,但他想出一个例子是世界上最困难的时刻。”

        我想拆分一些消息“但保留它是一个单一的字符串”瞧!

      • 结果:Discerningbetween'the single quote\'s double purpose'asa'quote marker',like",anda'a cotraction\'s marker.'.、 p>

        Ifyouaskedthe authorandhewasspeaking >、inthethirdperson,@ 987654349@wouldsay'CFQueryParam\'s example is contrived, and he knew that but he had the world\'s most difficult time thinking up an example.'

        SomemessageIwant tosplit'but keeping this a\'s a single string'Voila!

      【讨论】:

      • 此模式与Voila!之前的最后一个空格不匹配!
      • @alphabravo 你是对的(当然),我正在针对修改后的字符串进行测试。但是,我完全改变了我的正则表达式,现在它完美匹配。
      猜你喜欢
      • 2015-09-14
      • 2015-12-27
      • 2022-11-22
      • 1970-01-01
      • 2010-09-05
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      相关资源
      最近更新 更多