使用R中的正则表达式在文本文件中标识字符串

使用R中的正则表达式在文本文件中标识字符串,r,regex,R,Regex,这是我关于堆栈溢出的第一篇文章,我将尽可能简洁地解释我的问题 问题很简单。我试图识别包含字母数字字符的字符串和带有符号的字母数字字符,并将它们删除。我查看了Stack overflow中以前的问题,找到了一个看起来不错的解决方案 我在一些示例数据上尝试了notepad++中提供的正则表达式(稍微修改),只是想看看它是否有效(是的,它有效)。然后,我继续在R中使用相同的正则表达式,并使用gsub将字符串替换为“”(下面给出了代码) 预期的结果将是: > output1 abc def

这是我关于堆栈溢出的第一篇文章,我将尽可能简洁地解释我的问题

问题很简单。我试图识别包含字母数字字符的字符串和带有符号的字母数字字符,并将它们删除。我查看了Stack overflow中以前的问题,找到了一个看起来不错的解决方案

我在一些示例数据上尝试了notepad++中提供的正则表达式(稍微修改),只是想看看它是否有效(是的,它有效)。然后,我继续在R中使用相同的正则表达式,并使用gsub将字符串替换为“”(下面给出了代码)

预期的结果将是:

> output1
  abc def ghi                 abcd efgh WQWEQtWe_232 

> output2
  abc def ghi WQE34324Wweasfsdfs23234                abcd efgh  
我想我可能忽略了一些非常明显的事情

感谢您提供的任何帮助


谢谢

您的输出不会打印两次,而是作为命名向量输出。未加引号的行是元素名称,即输出本身中带引号的行。通过检查输出的长度可以看到这一点:

length( sapply( sample, replace_alnum ) )
# [1] 2
所以你知道这里只有两个元素

如果希望它们不带名称,可以在输出时取消命名向量:

unname( sapply( sample, replace_alnum ) )
# [1] "abc def ghi WQE34324Wweasfsdfs23234" "abcd efgh WQWEQtWe_232"
或者,您可以根据自己的喜好将其重命名为:

output <- sapply( sample, replace_alnum )
names( output ) <- c( "name1", "name2" )
output
#              name1                                 name2 
# "abc def ghi WQE34324Wweasfsdfs23234"              "abcd efgh WQWEQtWe_232" 

output不知道这种基于正则表达式的方法是否真的很好,但如果我们假设:

  • alnumsym“words”是由空格和字符串的开始/结束分隔的非空白块
  • alnum单词是由字母/数字组成的块,用非字母/数字或字符串的开头/结尾分隔
那么,你可以使用

sample <- c("abc def ghi WQE34324Wweasfsdfs23234", "abcd efgh WQWEQtWe_232")
gsub("\\b(?=\\w*[a-z])(?=\\w*[A-Z])(?=\\w*\\d)\\w{8,}", "", sample, perl=TRUE) ## replace_alnum
gsub("(?<!\\S)(?=\\S*[a-z])(?=\\S*[A-Z])(?=\\S*[0-9])(?=\\S*[_-])[A-Za-z0-9_-]{8,}", "", sample, perl=TRUE) ## replace_alnumsym
示例
看

模式1详细信息

  • \\b
    -前导词边界(我们需要匹配一个词)
  • (?=\\w*[a-z])
    -(正向前瞻)在0+字字符(
    \w*
    )之后必须有一个小写ASCII字母
  • (?=\\w*[A-Z])
    -此单词内必须有大写ASCII字母
  • (?=\\w*\\d)
    -还有一个数字
  • \\w{8,}
    -如果以上所有条件都匹配,则匹配8+字字符
注意为了避免匹配
\uu
\w
匹配
\u
),您需要将
\w
替换为
[^\w\u]

模式2详细信息

  • (?-(负查找)当前位置左侧不能立即显示任何非空白(空白或字符串开头应在前面)
  • (?=\\S*[a-z])
    -在0+非空白字符之后,必须有一个小写ASCII字母
  • (?=\\S*[A-Z])
    -非空白块必须包含大写ASCII字母
  • (?=\\S*[0-9])
    -和一个数字
  • (?=\\S*[[u-])
    -或者
    或者
    -
  • [A-Za-z0-9_-]{8,}
    -如果上述所有条件都匹配,则匹配8+ASCII字母、数字或
    -

请检查。谢谢……这很有效……非常感谢!!!你能提供一个正则表达式的解释吗?……那真的很有帮助……你已经接受了另一个答案。如果它对你有用,就用它。@Wiktor Stribizew你的解决方案比我的好得多。如果你想发布答案,我很乐意承认这些分数。@rosscova:如果你坚持,我会发布的有一些解释。嗨…谢谢你的解释!但是,我仍然面临着regex不在R中工作的问题。有什么解决方案吗?你是否试图分别分析每个文本字符串(用空格分隔)?我正在查看字符串向量,希望从每个字符串中删除子字符串(用空格分隔)匹配正则表达式。非常感谢您提供的解决方案…非常感谢!!!但我只是好奇…为什么它不直接作用于完整的字符串…为什么先将其更改为列表?它不应该自动识别子字符串并替换它吗?不。空格是字符串的一部分,所以
gsub
正在分析整个字符串e字符串作为一部分。字符串作为一个整体没有满足您的正则表达式测试,因此它没有被替换。
output <- sapply( sample, replace_alnum )
names( output ) <- c( "name1", "name2" )
output
#              name1                                 name2 
# "abc def ghi WQE34324Wweasfsdfs23234"              "abcd efgh WQWEQtWe_232" 
# split by space (leaving results in separate list items for recombining later)
input <- sapply( sample, strsplit, split = " " )

# apply your function on each list item separately
output <- sapply( input, replace_alnumsym )

# recombine each list item as they looked at the start
output <- sapply( output, paste, collapse = " " )
output <- unname( output )    

output
# [1] "abc def ghi WQE34324Wweasfsdfs23234" "abcd efgh "
output <- trimws( output )
output
# [1] "abc def ghi WQE34324Wweasfsdfs23234" "abcd efgh"
sample <- c("abc def ghi WQE34324Wweasfsdfs23234", "abcd efgh WQWEQtWe_232")
gsub("\\b(?=\\w*[a-z])(?=\\w*[A-Z])(?=\\w*\\d)\\w{8,}", "", sample, perl=TRUE) ## replace_alnum
gsub("(?<!\\S)(?=\\S*[a-z])(?=\\S*[A-Z])(?=\\S*[0-9])(?=\\S*[_-])[A-Za-z0-9_-]{8,}", "", sample, perl=TRUE) ## replace_alnumsym