【问题标题】:How to match non-escaped quoted strings and also non-quoted strings?如何匹配非转义引号字符串和非引号字符串?
【发布时间】:2019-07-14 00:12:06
【问题描述】:

我有一个包含单引号、双引号和转义引号的字符串:

告诉自己“你很棒”,然后说“谢谢”感觉“有点“好”

我想提取一个正则表达式:

  1. 单引号字符串
  2. 双引号字符串
  3. 不在引号中的字符串

预期结果:以下组

  1. 告诉自己
  2. 你是\'伟大的\'
  3. 然后说
  4. 谢谢
  5. 感觉
  6. 一个“小”不错

要求:不要返回引号,并忽略转义的引号

我目前所拥有的:

Regex #1 返回单引号和双引号 (source):

((?<![\\])['"])((?:.(?!(?<![\\])\1))*.?)\1

结果:

正则表达式 #2 返回不带引号的字符串:

((?<![\\])['"]|^).*?((?<![\\])['"]|$)

结果:

问题:

  1. 我无法使 regex #2 将未引用的字符串放入一致的组中
  2. 我无法将正则表达式 #1 和 #2 组合起来以在一个正则表达式函数中返回所有字符串

【问题讨论】:

  • @Emma, Javascript
  • 6和7错了,应该是a \"little\" nice
  • @sln,哎呀。是的,你是对的。固定。
  • @Emma,我需要维护组要求。我总是可以解决使用 javascript 的问题,但我的目标是看看是否有免费的 javascript 解决方案。

标签: javascript regex regex-lookarounds regex-group


【解决方案1】:

这样的事情怎么样:

(?<!\\)'(.+?)(?<!\\)'|(?<!\\)"(.+?)(?<!\\)"|(.+?)(?='|"|$)

Demo.

这背后的基本思想是,它首先尝试将带有引号的字符串匹配,这样之后剩下的就是没有被引号括起来的字符串。您将在捕获组中拥有所有匹配的字符串(不包括引号)。

缩短版:

(?<!\\)(['"])(.+?)(?<!\\)\1|(.+?)(?='|"|$)

Demo.


如果您不想使用捕获组,您可以调整它以使用如下 Lookarounds:

(?<=(?<!\\)').+?(?=(?<!\\)')|(?<=(?<!\\)").+?(?=(?<!\\)")|(?<=^|['"]).+?(?=(?<!\\)['"]|$)

Demo.

缩短版:

(?<=(?<!\\)(['"])).+?(?=(?<!\\)\1)|(?<=^|['"]).+?(?=(?<!\\)['"]|$)

Demo.

【讨论】:

  • 这并不能解决问题。我需要根据要求忽略转义引号。例如you are 不应返回,而 you are \'great\' 应作为一个组返回。
  • @Wronski 我的错!固定。
  • 太棒了!然而,它并没有解决将返回的字符串放入一致的组的问题。我想我需要通过一些额外的 javascript 来处理这个问题。
  • @Wronski 我不确定你所说的“一致组”是什么意思,但我添加了另一个不使用捕获组的解决方案,这样你就可以将预期值作为整个匹配.
  • @Wronski 我添加了两种解决方案的缩短版本。随意使用缩短的或更详细的。
【解决方案2】:

JS 版本

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

https://regex101.com/r/5xfs7q/1


PCRE - 专业级,超级版..

(?|(?|\s*((?:[^'"\\]|(?:\\[\S\s][^'"\\]*))+)(?&lt;!\s)\s*|\s+(*SKIP)(*FAIL))|(?&lt;!\\)(?|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|'([^'\\]*(?:\\[\S\s][^'\\]*)*)')|([\S\s]))

https://regex101.com/r/Tdyd3y/1

这是我见过的最干净、最好的一个。 Wsp 修剪和正则表达式仅包含一个捕获组。

解释

 (?|                           # BReset
      (?|                           # BReset
           \s*                           # Wsp trim
           (                             # (1 start), Non-quoted data
                (?:
                     [^'"\\] 
                  |  (?: \\ [\S\s] [^'"\\]* )
                )+
           )                             # (1 end)
           (?<! \s )
           \s*                           # Wsp trim
        |                              # or,
           \s+ (*SKIP) (*FAIL)           # Skip intervals with all whitespace 
      )
   |  
      (?<! \\ )                     # Not an escape behind
      (?|                           # BReset
           " 
           (                             # (1 start), double quoted string data
                [^"\\]* 
                (?: \\ [\S\s] [^"\\]* )*
           )                             # (1 end)
           "
        |                              # or,
           '
           (                             # (1 start), single quoted string data
                [^'\\]* 
                (?: \\ [\S\s] [^'\\]* )*
           )                             # (1 end)
           '
      )
   |  
      ( [\S\s] )                    # (1), Pass through, single char
                                    # Un-balanced " or ' or \ at EOF
 )

【讨论】:

  • @Wronski - 没问题。如果您有兴趣,我已经为 PCRE 添加了专业版。
猜你喜欢
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 2014-05-02
  • 2018-12-21
  • 2021-07-12
  • 2011-12-04
  • 1970-01-01
  • 2011-01-30
相关资源
最近更新 更多