如何删除特定的字符集而不是其他字符集?

How do I remove particular sets of characters and not others?

由于拙劣的字符解码,我有一组标题看起来像这样,特殊字符后跟其他字符,如 ñ,原始字符中没有:

Päivän Jälkeen
Tuuli kääntyä voi
Päivän Jälkeen
Tuuli kääntyä voi
「Eurotrash」
Le Désert N'Est Plus En Afrique

我知道我可以使用类似 s:g / ... / ... / 的东西,但我不确定如何只匹配特殊字符 () 而不是捕获撇号、空格等。

当使用 \W 尝试捕获“不是 'word' 中使用的字符”时,我 运行 遇到了匹配撇号、空格等的问题。

因此,我的问题是,在尝试从字词中删除这些字符时,我遗漏了什么有用的东西?

TL;DR 两个解决方案加上一些进一步的讨论。

适用于您的示例的最简单的解决方案

<:So>

例如:

say
  S:g /<:So>//
given
  'Päivän Jälkeen' 

# Pñivñn Jñlkeen

上述解决方案的解释

首先,一个看似简短但会让你很快深入的解释:

现在稍微长一点的解释可能比上面概述的方法更容易理解这些东西:

  • 在 Raku 正则表达式中,<...>... 为真的一般断言。 许多 可以是 ... 的变体。¹

  • 一种变体是当前字符与字符 class 或 class 的某种组合相匹配,由 <...> 指定。这个 Raku 字符 class 表达式 ... 可以有 许多 变体。²

  • 字符 class 表达式的一种变体是显式 Unicode 字符 属性 值;它将匹配具有该 Unicode 字符 属性 值的字符。 Unicode 字符 属性 及其值可以有 许多 变体; <:So> 是一个示例,适用于您的场景。³

这是我为您的场景 select 那个角色 class 所经历的过程:

  1. 我使用 util.unicode.org 托管实用程序查看 properties of the character。⁴

  2. 我重点关注 table 左栏顶部附近列出的 General_Category 属性。这是在 Raku 正则表达式中指定的常见 属性。您通常不会通过写 <:General_Category...> 来指定它,... 是类别,而是只写 <:category>,其中 category 是类别。

  3. 我记下了 General_Category 值(下一列):Other_Symbol。如果您阅读与 General_Category 属性 相关的 Unicode 或 Raku 文档,您会看到 SoOther_Symbol.

    的简称
  4. 要在 Raku 中指定 Unicode 属性,请使用 Raku 的冒号对文字语法编写它。键可以是许多 Unicode 属性中的任何一个。⁵ 因此,要匹配具有 So 属性 的字符,请在正则表达式中写入 <:So>

  5. 要从字符串中删除具有 class 的字符,一种选择是使用 s/// 结构:

    say
      S:g /<:So>//
    given
      'Päivän Jälkeen' 
    
    # Pñivñn Jñlkeen
    

获得相同结果的另一种方法

您可能想对字符 classes / 个字符进行“算术运算”,加一些,减一些:

say
  S:g / <+ [\W] - [\s] - ['] > //
given
  'Päivän Jälkeen'

# Pñivñn Jñlkeen

<+ [\W] - [\s] - ['] > 读作“不是单词字符,也不是 space 字符,也不是 '”。

参见 Enumerated character classes and ranges in the Character Class section of Raku's doc for further details of using enumerated classes (using < [...] >) and adding/subtracting classes (using + and -) and/or

对于某些用例,这种方法可能会简化获得您想要 and/or 表达结果的精确结果,这样其他人或未来的您就可以更轻松地维护它。但这完全取决于我将在下一节中讨论的内容。

进一步讨论您的问题:“等等”

I am unsure of how to capture just the special characters as opposed to capturing apostrophes, spaces, and so on.

假设您使用了我展示的一种或另一种或两种解决方案。你怎么知道他们真的是你想要的?答案是您需要探索 Unicode。像 \w/\W\s/\S 等字符 class 只是 Unicode 属性的便捷快捷方式,所以如果你想确定发生了什么。鉴于这一切最终都归结为 Unicode 属性,让我们讨论 <:So> 解决方案。

正如我们在上面看到的,General_Category 属性(如上面的实用程序 linked 所示)是 link/value Other_Symbol.

如果单击后者 link,您将看到对应于 Unicode Other_Symbol 字符 class 的页面。这是一大堆混乱的 black-and-white 符号和彩色表情符号,然后是其他符号的有序列表。超过6000个字符!

此字符 class 是否包含可归类为“spaces”的字符?我几乎可以肯定它不会,但这将由你来解决,而不是我。 “撇号”呢?与“spaces”相比,我对此不太确定,但我再次认为它不会包含可称为或归类为“撇号”的字符。 Other_Symbol字符class是否包含“等等”?!?也许抛硬币?也许在页面浏览器中搜索 Other_Symbol 页面上的特定字符?


当我不使用托管在 util.unicode.org 或类似工具上的工具时,我偶尔用来探索 Unicode 字符 classes 的一种方法是此 Raku 代码的变体:

say (^0x10FFFF)».chr.grep(/ <:So> /)

(^0x10FFFF) 是一种指定整数 Range 对应于所有1,114,112 个合法的 Unicode 代码点。 ».chr 迭代范围,生成从 0 开始的整数列表,对每个整数应用 .chr,从而生成与给定整数对应的 Unicode 字符。然后 .grep(/ <:So> /) 只保留 General_CategoryOther_Symbol.

的字符

也就是说,那会很慢。您会想找到探索 Unicode 的其他方法。

其他选项包括 util.unicode.org 工具和 Raku 社区的 Unicodable which you can run by visiting the #raku IRC channel 并输入 u: ....

讨论“$_ ~~ s:g / \├ / /;

when I attempt to directly escape the character in my regex via $_ ~~ s:g/ \├ / /;, the result stays the same

我无法重现。

我想你刚刚搞糊涂了。

如果您仍然坚信自己是对的,请出示 MRE

脚注

¹ Raku 的很大一部分力量在于其强大的正则表达式。 的很大一部分是通过一般形式 <...>.

表达的

² 字符 class 语法包括从旧正则表达式格式继承的旧样式语法,例如 \s 以匹配 whitespace。但它们都只是 Unicode 属性或字符的快捷方式,而不是 ASCII 属性或字符的快捷方式,现在有更多的变化。

³ 如果您只浏览文档,您可能会认为 Raku 正则表达式只能匹配 Unicode 的 General_Category 属性。但是如果您查看代码示例,您会发现还有 <:Script<Latin>><:Block('Basic Latin')>。 (但它们是什么?)然后当您看到 util.unicode.org 属性 浏览器显示的大量属性时,您会意识到还有 大量 可以匹配的属性. Rakudo 匹配其中的许多但不是全部。有关详细信息,请参阅 What are all the Unicode properties a character will match?

⁴ 或许将 links 添加到 Raku 文档中的一些实用程序中会是一件好事。 And/or creating/hosting 使用 Raku 的变体。

⁵ 我怀疑 Raku 在 Unicode 属性之外定义了一些形式为 <:foo> 的额外内容。例如,我知道 :space 有效(它匹配 ASCII space)但怀疑它不是 Unicode 属性。 Otoh 对我来说这听起来完全错误,并且与我对 Raku 设计的期望背道而驰。如果我确实找到了一种或另一种方式,我将更新此脚注。