【问题标题】:Where is this whitespace hiding?这个空白隐藏在哪里?
【发布时间】:2012-07-28 16:40:33
【问题描述】:

我有一个字符向量,它是通过pdftotext(命令行工具)抓取的一些 PDF 文件。

一切都(幸福地)排列整齐。然而,这个向量充满了一种我的正则表达式无法理解的空格:

> test
[1] "Address:"              "Clinic Information:"   "Store "                "351 South Washburn"    "Aurora Quick Care"    
[6] "Info"                  "St. Oshkosh, WI 54904" "Phone: 920‐232‐0718"   "Pewaukee"  

> grepl("[0-9]+ [A-Za-z ]+",test)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

> dput(test)
c("Address:", "Clinic Information:", "Store ", "351 South Washburn", 
"Aurora Quick Care", "Info", "St. Oshkosh, WI 54904", "Phone: 920‐232‐0718", 
"Pewaukee")

> test.pasted <- c("Address:", "Clinic Information:", "Store ", "351 South Washburn", 
+                  "Aurora Quick Care", "Info", "St. Oshkosh, WI 54904", "Phone: 920‐232‐0718", 
+                  "Pewaukee")

> grepl("[0-9]+ [A-Za-z ]+",test.pasted)
[1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE

> Encoding(test)
[1] "unknown" "unknown" "unknown" "unknown" "unknown" "unknown" "unknown" "unknown" "unknown"

> Encoding(test.pasted)
[1] "unknown" "unknown" "unknown" "unknown" "unknown" "unknown" "unknown" "UTF-8"   "unknown"

很明显,dput 中没有分配一些字符,如下面的问题所示:

How to properly dput internationalized text?

我无法复制/粘贴整个向量....如何搜索和销毁这个非空白空格?

编辑

很明显,我什至没有说清楚,因为答案无处不在。这是一个更简单的测试用例:

> grepl("Clinic Information:", test[2])
[1] FALSE
> grepl("Clinic Information:", "Clinic Information:") # Where the second phrase is copy/pasted from the screen
[1] TRUE

在屏幕上和dput 输出中打印的单词“Clinic”和“Information”之间有一个空格,但字符串中的任何内容都不是标准空格。我的目标是消除这个问题,这样我就可以正确地 grep 那个元素了。

【问题讨论】:

  • 那个空白不在向量本身,它只是在它的显示方式中。
  • 看看lapply(test[4], utf8ToInt),看看里面有没有大数字。
  • @AlanCurry &gt; lapply(test[4], utf8ToInt) [1] 51 53 49 160 83 111 117 116 104 160 87 97 115 104 98 117 114 110
  • 160 是你的问题。这是一个不间断的空间。您可以通过在 perl 风格的正则表达式中使用 Unicode 类别来匹配它(以及其他一些奇怪的空格类型): grepl("[0-9]+\\p{Zs}[A-Za-z ]+" ,test,perl=TRUE)
  • @AlanCurry,你能把它作为答案发布吗?

标签: regex r


【解决方案1】:

将我的评论升级为答案:

您的字符串包含一个不间断空格 (U+00A0),当您粘贴它时,该空格已转换为正常空格。使用 perl 风格的正则表达式可以轻松匹配 Unicode 中所有奇怪的类似空格的字符:

grepl("[0-9]+\\p{Zs}[A-Za-z ]+", test, perl=TRUE)

perl 正则表达式语法是\p{categoryName},额外的反斜杠是包含反斜杠的字符串语法的一部分,而“Zs”是“分隔符”Unicode 类别、“空格”子类别。仅针对 U+00A0 字符的更简单方法是

grepl("[0-9]+[ \\xa0][A-Za-z ]+", test)

【讨论】:

  • 我很困惑。 test[2] 无论如何都不会匹配,它没有数字来匹配 [0-9] 部分。
  • 你当然是对的。在盲目运行它之前应该阅读正则表达式。一旦我把有问题的数字弄出来就可以完美地工作,谢谢!
【解决方案2】:

我认为您在使用尾随和前导空格。如果是这样,这个功能可能会起作用:

Trim <- function (x) gsub("^\\s+|\\s+$", "", x)

还要注意标签等,这可能很有用:

clean <- function(text) {
    gsub("\\s+", " ", gsub("\r|\n|\t", " ", text))
}

所以使用 clean 然后使用 Trim,如下所示:

Trim(clean(test))

还要注意短划线 (-) 和短划线 (-)

【讨论】:

    【解决方案3】:

    我没有看到空格有什么异常,但电话号码中的破折号是U+2010 (HYPHEN),而不是 ASCII 连字符 (U+002D)。

    【讨论】:

      【解决方案4】:
      test <- c("Address:", "Clinic Information:", "Store ", "351 South Washburn", 
      "Aurora Quick Care", "Info", "St. Oshkosh, WI 54904", "Phone: 920‐232‐0718", 
      "Pewaukee")
      
      > grepl("[0-9]+ [A-Za-z ]+",test)
      [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
      
      
      library(stringr)
      test2 <- str_trim(test, side = "both")
      
      > grepl("[0-9]+ [A-Za-z ]+",test2)
      [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
      # So there were no spaces in the vector, just the screen output in this case.
      

      【讨论】:

        猜你喜欢
        • 2010-10-06
        • 2019-11-18
        • 1970-01-01
        • 2021-02-21
        • 1970-01-01
        • 1970-01-01
        • 2010-11-17
        相关资源
        最近更新 更多