【问题标题】:Word boundaries handling for punctuation characters in regexp in RR中正则表达式中标点符号的字边界处理
【发布时间】:2015-10-12 15:34:25
【问题描述】:

虽然Replace two dots in a string with gsub 回答了有关替换“.”等标点字符的问题,但它似乎不适用于单词边界。例如,

text100 <- "My # is 1234"
text1 <- gsub("\\b#\\b","hash",text100)
> text1
[1] "My # is 1234"

# 没有被替换。如何解决这个问题?

请注意,不应替换多个#。例如,

'##' 不应替换为 'hash' 或 'hashhash'。

# 后面或前面的任何图形字符都应该 不被替换(例如,'.#' 不应该被替换)

【问题讨论】:

  • 这不会解决单词边界问题。例如: text100> text1 text1 [1] "My numberhashnumber hash is 1234" 注意number#号码不应该被替换。
  • 请将多个连续哈希替换的要求添加到问题本身。
  • @stribizhev 完成。谢谢。

标签: regex r punctuation word-boundary word-break


【解决方案1】:

您的正则表达式不起作用,因为散列不是单词字符,并且您需要单词字符位于散列的两侧。

如果您想确保# 符号周围没有单词字符,请使用 Perl 风格的正则表达式替换:

text100 <- "My # is 1234"
gsub("(?<!\\w)\\#+(?!\\w)","hash",text100, perl=T)

IDEONE demo

后视(?&lt;!\\w) 确保# 之前没有字母、数字或下划线,而(?!\\w) 前瞻确保其后没有字母、数字或下划线。

为避免过度转义,您可以将哈希放入字符类中:

"(?<!\\w)[#]+(?!\\w)"

在散列符号后使用+ 量词将确保多个连续散列被替换为一个单词“散列”。

更新

适用于您更新示例的解决方案:

gsub("(?<!\\w|#)[#](?!\\w|#)", "hash", text100, perl=T)

这里,(?&lt;!\\w|#) 将确保散列前面没有单词字符或散列符号,而(?!\\w|#) 否定前瞻将确保散列符号后面没有单词字符或散列符号。

another demo

【讨论】:

  • 一个更粗略的选择是捕获相邻的非单词事物并将它们放回替换中:sub("([^\\w])#([^\\w])","\\1hash\\2",text100)
  • @Frank:这在一个条件下很好:哈希不能出现在字符串的开头和结尾。
  • @stribizhev 虽然这适用于多种组合,但它似乎不适用于 '##' : > text100 text1 text1 [1] "我的号码#number hash hashhash #number number # is 1234" 我不希望 '##' 被替换为 hashhash。
  • @stribizhev 感谢您的出色回答! 1 次或多次出现的解决方案不适用于我的上下文,因此 Frank 建议在检查中添加 '|#' 将是适合我情况的理想解决方案。我会相信你的两个答案。非常感谢你们!
  • @stribizhev 如果您认为合适,请随时将我的评论编辑到您的答案中(这就是我发表评论而不是发布单独答案的原因)。感谢前瞻/后向的课程,我仍在学习。
猜你喜欢
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 2016-05-13
相关资源
最近更新 更多