【问题标题】:R - grep() matches, but str_remove_all() fails with non-ascii charactersR - grep() 匹配,但 str_remove_all() 因非 ascii 字符而失败
【发布时间】:2019-04-06 01:03:27
【问题描述】:

我正在解析 PDF 中的表格并尝试清理我的读数。我正在尝试对我的 OCR 中的一些常见故障做一个简单的str_remove_all()。我创建了一个与我的字符串匹配的正则表达式,但是,当我将正则表达式放入 str_remove_all() 时,它失败了。请看下面的代码:

> regexpattern <- '^(\\s*[[:punct:]]*\\s*)+|^\\s*\\d{1,2}\\s*$|^\\s+$|(^\\s* 
[[:ascii:]]{1}\\s*$)|(^\\s*[^[:ascii:]]{1}\\s*$)'

>   strg <- "Ú"

>  grep(regexpattern,strg, perl = T)
[1] 1

>  str_remove_all(strg,regexpattern)
[1] "Ú"

关于为什么我的str_remove_all() 失败的任何想法?谢谢!

【问题讨论】:

  • str_remove_all() 需要两个参数,RDocumentationstr_remove_all(string, pattern)。 str_replace_all() 也失败了str_replace_all(strg,regexpattern, "") [1] "Ú"

标签: r regex stringi


【解决方案1】:

编辑:删除了先前的答案,虽然技术上可行,但不是问题。

问题是您的正则表达式没有按照我认为的那样做。正则表达式中的第一个选择是\\s*[[:punct]]*\\s*。这些元素都不需要存在,这意味着 everything 将匹配并且不会检查您的任何其他替代方案。因此,当stringr::str_remove_all 使用该正则表达式时,它将遍历第一个字符的备选方案,使用第一个备选方案,因为它匹配,并忽略继续前进的字符。将其更改为\\s*[[:punct]]+\\s*,您将获得更好的成功。

> regexpattern <- '^(\\s*[[:punct:]]*\\s*)+'
> grep(regexpattern,strg, perl = T, value=TRUE)
[1] "Ú"
> regexpattern <- '^(\\s*[[:punct:]]+\\s*)+'
> grep(regexpattern,strg, perl = T, value=TRUE)
character(0)
> regexpattern <- '^(\\s*[[:punct:]]+\\s*)+|^\\s*\\d{1,2}\\s*$|^\\s+$|(^\\s*[[:ascii:]]{1}\\s*$)|(^\\s*[^[[:ascii:]]]{1}\\s*$)'
> str_remove_all(strg, regexpattern)
[1] ""

【讨论】:

  • @MakoEyedSoldier - 更新了答案,为您提供所需的内容
  • 是的......这就是原因。盯着同一段代码看几个小时,你的大脑就会变成土豆。完全错过了我的贪婪指标。非常感谢你让我直截了当!
【解决方案2】:

您的正则表达式不会删除所有非 ASCII 字符。

grep('^(\\s*[[:punct:]]*\\s*)+|^\\s*\\d{1,2}\\s*$|^\\s+$|(^\\s* 
     [[:ascii:]]{1}\\s*$)|(^\\s*[^[:ascii:]]{1}\\s*$)',
     c("Úa", "Ú", "b"), perl = TRUE, value=TRUE)
[1] "Úa" "Ú"  "b" 

试试"[^u0000-u007F]+"

grep("[^u0000-u007F]+", c("Úa", "Ú", "b"), perl = TRUE, value=TRUE)
[1] "Úa" "Ú" 

然后str_remove_all() 也按预期工作:

library(stringr)
str_remove_all(c("Úa", "Ú", "b"), "[^u0000-u007F]+")
[1] "a" ""  "b"

【讨论】:

  • 不,不是我投反对票 :) 感谢您的帮助,您帮助我缩小了一些范围,但 regexpattern &lt;- ^\\s*[^u0000-u007F]{1}\\s*$ 有效,regexpattern &lt;- "^(\\s*[[:punct:]]*\\s*)+|^\\s*\\d{1,2}\\s*$|^\\s+$|(^\\s*[[:ascii:]]{1}\\s*$)|^\\s*[^u0000-u007F]{1}\\s*$" 无效。我已经将我的替换分为两个步骤,但我真的很想只进行一个正则表达式检查
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2018-04-08
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
相关资源
最近更新 更多