如何在空白模式之间进行选择?

IT小君   2021-11-02T22:10:18

Oracle 模式文档中,描述了用于匹配空白的三种不同模式:

  1. \s
  2. \p{空格}
  3. \p{javaWhitespace}

我想知道每种方法的特殊性以及如何知道如何选择正确的方法。我刚刚注意到\p{javaWhitespace}包含更多的空间类型。

评论(3)
IT小君

我宁愿使用第一个。

  • 紧凑
  • 它与许多其他语言以及正则表达式理论中的符号相同
  • \p{javaWhitespace}包括FILE SEPARATORGROUP SEPARATOR等等...看到这个在不需要这些时使用它可能会使其他人感到困惑。
  • 一般来说,我希望另一个程序员知道什么\s是,而我希望他们仔细检查\p{javaWhitespace}. 您不希望这样,因为它会降低代码清晰度并在调试过程中增加不必要的负担。
2021-11-02T22:10:18   回复
IT小君

\s是最短也是最不可移植的选项来指定空格字符尽管将 Java 代码移植到其他语言的情况很少见,但更多的是将一种正则表达式引擎的语法知识移植到另一种语言。有许多正则表达式引擎使用类似 Perl 的语法,因此对相同语法的解释差异\s使程序员感到困惑。

除了空格 (ASCII 32)、换行符 ( \n, ASCII 10)、水平制表符 ( \t, ASCII 9)、回车 ( \r, ASCII 13) 和换页 ( \f, ASCII 12) 之外,不同引擎之间没有达成共识一个空格字符

  • Java、POSIX (ASCII):还包括垂直制表符 (ASCII 11)。Java 似乎在这里遵循 POSIX 标准。

  • JavaScript(5.1版):根据规范(逐字逐句),除了常见的5种之外,它还包括:

    • Unicode 类别Zs(分隔符/空格)\u2028(行分隔符)、\u2029(段落分隔符)。它基本上包括 Z 类(分隔符)下的所有字符。

      实际上\u2028是类别Zl (Separator/Line)\u2029的唯一成员,并且是类别Zp (Separator/Paragraph)的唯一成员根据措辞,规范的当前版本可能排除了对这 2 个类别的任何进一步扩展。

    • 垂直标签 \v
    • 字节顺序标记又名零宽度无间断空间 \ufeff
  • Perl,PCRE(ASCII 模式):\v从 Perl 5.18 添加的垂直选项卡作为实验。5.18之前,只匹配5个普通的。

  • Perl(Unicode 模式):除了 5 个常见的

    • Unicode 类别 Z(分隔符)
    • \v从 Perl 5.18 添加的垂直选项卡作为实验。
    • 下一行 (NEL) \u0085
    • 蒙古语元音分隔符 \u180e
  • .NET(默认):除了 5 个常见的

    • Unicode 类别 Z(分隔符)
    • 垂直标签 \v
    • 下一行 (NEL) \u0085
  • Java (Unicode):从 Java 7 开始,Pattern 类包含一个新标志UNICODE_CHARACTER_CLASS,它使预定义字符类POSIX 字符类符合Unicode 技术标准 #18:Unicode 正则表达式当标志处于活动状态时,预定义字符类和对应的POSIX 字符类将变得等效(匹配相同的东西)。

    字符列表与 .NET 相同。

这足以让一个人发疯!


\p{Space}是更“稳定”的选择,因为它遵循POSIX标准的默认模式,统一技术标准#18:Unicode的正则表达式UNICODE_CHARACTER_CLASS

如果您使用 POSIX 字符类,符合 POSIX 的实现将在 ASCII 模式下具有相同的行为,并且遵循该建议的 Unicode 正则表达式引擎将在 Unicode 模式下具有(几乎)相同的行为。

\s\p{Space}在 Java 中是等价的,无论标志如何。如果您\s在 Java 中使用,您可以确定您遵循了一些标准/建议。只是它没有向大多数程序员宣布这个事实。


\p{isJavaWhitespace}根据Java 的定义匹配空格该函数的名称极具误导性。

2021-11-02T22:10:18   回复
IT小君

除非您有使用其他选项的特定原因,否则我会保持简单并使用 \s

2021-11-02T22:10:19   回复