【问题标题】:Is there a way to have a character match a conjunction of character classes?有没有办法让字符匹配字符类的结合?
【发布时间】:2021-12-06 13:17:25
【问题描述】:

我试图让一个正则表达式描述一个单引号分隔的字符串。 在字符串中,我可以有 任何可打印(或空白)字符(不是单引号),也可以是一系列两个单引号,这将是一个“转义”单引号。

[[:print:]] 字符类(也写为 \p{XPosixPrint})符合我想要允许的字符的要求...除了它还允许单个“单引号”(' )。这是我不希望发生的。

那么,有没有一种简单的方法可以做到这一点,例如,描述一个字符以同时匹配两个表达式(如 [[:print:]] 和 [^'] ),还是我必须创建一个枚举我允许(或禁止)的所有内容的自定义字符类?

【问题讨论】:

标签: regex perl


【解决方案1】:
/(?!')\p{Print}/                     # Worst performance and kinda yuck?
/\p{Print}(?<!')/                    # Better performance but yuckier?
/[^\P{Print}']/                      # Best performance, but hard to parse.[1]
use experimental qw( regex_sets );   # No idea why still experimental.
/(?[ \p{Print} - ['] ])/             # Best performance and clearest.
/[^\p{Cn}\p{Co}\p{Cs}\p{Cc}']/       # Non-general solution.
                                     # Best performance but fragile.[2]

\p{Print}\p{XPosixPrint} 的别名。


  1.    char that is (printable and not('))
     = char that is (not(not(printable and not('))))
     = char that is (not(not(printable) or not(not('))))
     = char that is (not(not(printable) or '))
     = [^\P{Print}']
    
  2. \p{Print} 包括除未分配、私人使用、代理和控制字符之外的所有字符。

    /[^\p{Cn}\p{Co}\p{Cs}\p{Cc}']/
    

    简称

    /[^\p{General_Category=Unassigned}\p{General_Category=Private_Use}\p{General_Category=Surrogates}\p{General_Category=Control}']/
    

    use experimental qw( regex_sets );   # No idea why still experimental.
    /(?[ !(
         \p{General_Category=Unassigned}
       + \p{General_Category=Private_Use}
       + \p{General_Category=Surrogates}
       + \p{General_Category=Control}
       + [']
    ) ])/
    

【讨论】:

  • 我的 Perl 不喜欢带有 /(?[ \p{Print} - ['] ])/ 的版本我有 5.16.3,这是版本问题吗?
  • 如果您收到消息说找不到experimental.pm,那是因为您没有安装它。 (自 5.18.0 起,它随 Perl 提供。)如果您收到消息“Need perl 5.18.0 or later for feature regex_sets”,那么,这很容易解释。
  • 请注意,5.16 于 2012 年发布(5.16.3 于 2013 年发布)。它并不新鲜。
  • 我不认为 我收到消息告诉我它需要 Perl 5.18.0,但我可能错过了它。它只是告诉我它不喜欢正则表达式中的语法。至于这个版本过时的一面,我完全同意你的看法,但我只能使用我被允许使用的工具(国家和大公司都是关于“验证”的工具)。所以我选择了“难以解析”的那个,它工作得很好。再次感谢。
  • Re "它只是告诉我它不喜欢正则表达式中的语法。",然后你漏掉了use experimental qw( regex_sets );
猜你喜欢
  • 2011-08-25
  • 2021-09-20
  • 1970-01-01
  • 2021-06-10
  • 2019-11-13
  • 2021-01-04
  • 2013-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多