R - grep() 匹配,但 str_remove_all() 因非 ascii 字符而失败
R - grep() matches, but str_remove_all() fails with non-ascii characters
我正在解析 PDF 中的 table 并尝试清理我的读数。我正在尝试对我的 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()
失败的任何想法?谢谢!
您的正则表达式没有删除所有非 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"
编辑:删除了先前的回答,虽然技术上可行不是问题。
问题是您的正则表达式没有按照您的预期进行。正则表达式中的第一个替代项是 \s*[[:punct]]*\s*
。这些元素中的 None 需要存在,这意味着 所有内容 都将匹配,并且 none 其他备选方案将被检查。因此,当 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] ""
我正在解析 PDF 中的 table 并尝试清理我的读数。我正在尝试对我的 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()
失败的任何想法?谢谢!
您的正则表达式没有删除所有非 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"
编辑:删除了先前的回答,虽然技术上可行不是问题。
问题是您的正则表达式没有按照您的预期进行。正则表达式中的第一个替代项是 \s*[[:punct]]*\s*
。这些元素中的 None 需要存在,这意味着 所有内容 都将匹配,并且 none 其他备选方案将被检查。因此,当 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] ""