首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R/regex with stringi/ICU:为什么'+‘被认为是非[:with:]字符?

R/regex with stringi/ICU:为什么'+‘被认为是非[:with:]字符?
EN

Stack Overflow用户
提问于 2014-10-14 04:48:48
回答 2查看 952关注 0票数 16

我正在尝试从字符串向量中删除非字母字符。我认为[:punct:]分组可以涵盖它,但它似乎忽略了+。这是否属于另一组字符?

代码语言:javascript
复制
library(stringi)
string1 <- c(
"this is a test"
,"this, is also a test"
,"this is the final. test"
,"this is the final + test!"
)

string1 <- stri_replace_all_regex(string1, '[:punct:]', ' ')
string1 <- stri_replace_all_regex(string1, '\\+', ' ')
EN

回答 2

Stack Overflow用户

发布于 2014-10-14 05:00:27

POSIX字符类需要包装在字符类中,正确的形式应该是[[:punct:]]。不要将POSIX术语“字符类”与通常称为正则表达式字符类的术语混淆。

此ASCII范围内的POSIX命名类匹配所有非控件、非字母数字、非空格字符。

代码语言:javascript
复制
ascii <- rawToChar(as.raw(0:127), multiple=T)
paste(ascii[grepl('[[:punct:]]', ascii)], collapse="")
# [1] "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"

虽然如果 locale 生效,它可能会改变 [[:punct:]]的行为...

R Documentation ?regex声明如下:某些命名的字符类是预定义的。它们的解释取决于语言环境(参见locales);解释是POSIX语言环境的解释。

开放组织LC_TYPE definition for punct说:

定义要分类为标点符号的字符。

在POSIX 语言环境中,不应包含<space>或alpha、digit或cntrl类中的任何字符。

在区域设置定义文件中,不应指定为关键字upper、lower、alpha、digit、cntrl、xdigit或作为<space>指定的字符。

然而,stringi包似乎依赖于ICU,而区域设置是ICU中的一个基本概念。

使用stringi包,我推荐使用Unicode Properties \p{P} and \p{S}

  • \p{P}可以匹配任何类型的标点符号。也就是说,它缺少POSIX类That包含的九个字符。这是因为Unicode将POSIX认为的标点符号分为两类,标点符号Symbols。这就是\p{S}应运而生的地方。

stri_replace_all_regex(string1,'\p{P}\p{S}',‘') #1 "this is a test“"this is a test”"this is a test“#3 "this is the final test”“this is the final test”“this is the final test”

  • 或从基数R回退到gsub,很好地处理了这个问题。

(‘[:test:] ',’‘,string1) #1“这是一个测试”“这也是一个测试”#3“这是最终测试”

票数 19
EN

Stack Overflow用户

发布于 2014-10-14 17:18:46

在类似POSIX的正则表达式引擎中,punct代表与ispunct()分类函数相对应的字符类(请查看类UNIX系统上的man 3 ispunct )。根据ISO/IEC9899:1990 (ISO C90),ispunct()函数测试除空格或isalnum()为true的字符以外的任何打印字符。但是,在POSIX设置中,哪些字符属于哪个类的详细信息取决于当前的区域设置。因此,这里的punct类不会导致可移植代码,有关更多详细信息,请参阅ICU user guide on C/POSIX Migration

另一方面,stringi所依赖的ICU库完全符合Unicode标准,它以自己的方式定义了一些charclasses -但是定义良好,而且总是可移植的。

特别地,根据Unicode标准,PLUS SIGN (U+002B)属于Symbol, Math (Sm)类别(而不是Puctuation Mark (P))。

代码语言:javascript
复制
library("stringi")
ascii <- stri_enc_fromutf32(1:127)
stri_extract_all_regex(ascii, "[[:punct:]]")[[1]]
##  [1] "!"  "\"" "#"  "%"  "&"  "'"  "("  ")"  "*"  ","  "-"  "."  "/"  ":"  ";"  "?"  "@"  "["  "\\" "]"  "_"  "{"  "}" 
stri_extract_all_regex(ascii, "[[:symbol:]]")[[1]]
## [1] "$" "+" "<" "=" ">" "^" "`" "|" "~"

因此,在这里您应该使用[[:punct:][:symbol:]][[:punct:]+]这样的字符集,或者更好的[\\p{P}\\p{S}][\\p{P}+]字符集。

有关可用字符类的详细信息,请查看?"stringi-search-charclass"。特别是,您可能会对ICU User Guide on UnicodeSetUnicode Standard Annex #44: Unicode character database感兴趣。HTH

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26348643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档