我正在努力以干凈的方式將逗號分隔的字串剝離為唯一的子字串:
x <- c("Anna & x, Anna & x", #
"Alb, Berta 222, Alb",
"Al Pacino",
"Abb cd xy, Abb cd xy, C123, C123, B")
我似乎對負字符類、負前瞻和反向參考的這種組合做得很好;然而讓我煩惱的是,在許多子字串中有不需要的空格:
library(stringr)
str_extract_all(x, "([^,] )(?!.*\\1)")
[[1]]
[1] " Anna & x"
[[2]]
[1] " Berta 222" " Alb"
[[3]]
[1] "Al Pacino"
[[4]]
[1] " Abb cd xy" " C123" " B"
如何細化模式以便不提取不需要的空白?
Desired result:
#> [[1]]
#> [1] "Anna & x"
#> [[2]]
#> [1] "Alb" "Berta 222"
#> [[3]]
#> [1] "Al Pacino"
#> [[4]]
#> [1] "Abb cd xy" "C123" "B"
編輯:
只是想用雙重否定前瞻來分享這個解決方案,它也很有效(感謝提出的許多有用的解決方案!)
str_extract_all(x, "((?!\\s)[^,] )(?!.*\\1)")
uj5u.com熱心網友回復:
將您的模式更改為以下模式:
str_extract_all(x, "(\\b[^,] )(?!.*\\1)")
[[1]]
[1] "Anna & x"
[[2]]
[1] "Berta 222" "Alb"
[[3]]
[1] "Al Pacino"
[[4]]
[1] "Abb cd xy" "C123" "B"
uj5u.com熱心網友回復:
您可以使用str_split獲取單個子字串,然后unique洗掉重復的字串。例如:
library(tidyverse)
str_split(x, ", ?") %>% map(unique)
#> [[1]]
#> [1] "Anna & x"
#>
#> [[2]]
#> [1] "Alb" "Berta 222"
#>
#> [[3]]
#> [1] "Al Pacino"
#>
#> [[4]]
#> [1] "Abb cd xy" "C123" "B"
如果您希望輸出作為唯一字串的單個向量,您可以執行以下操作:
str_split(x, ", ?") %>% unlist %>% unique
#> [1] "Anna & x" "Alb" "Berta 222" "Al Pacino" "Abb cd xy" "C123"
#> [7] "B"
在上面的代碼中,我們使用正則運算式", ?"在逗號或逗號后跟一個空格處進行拆分,這樣我們就不會以空格結束。為了將來參考,如果您確實需要洗掉前導或尾隨空格,您可以使用str_trim. 例如,如果我們使用了","instr_split我們可以執行以下操作:
str_split(x, ",") %>%
map(str_trim) %>%
map(unique)
uj5u.com熱心網友回復:
不完全是您所要求的,但是當問題變得更加復雜時,NLP 框架會有所幫助。
library(tidytext)
library(dplyr)
library(tibble)
tibble(text = x) %>%
rowid_to_column("stringid") %>%
unnest_regex(substring, text, pattern = ",", to_lower = FALSE) %>%
distinct(stringid, substring = trimws(substring))
# # A tibble: 7 x 2
# stringid substring
# <int> <chr>
# 1 1 Anna & x
# 2 2 Alb
# 3 2 Berta 222
# 4 3 Al Pacino
# 5 4 Abb cd xy
# 6 4 C123
# 7 4 B
uj5u.com熱心網友回復:
您需要從空格和逗號以外的字符開始匹配,然后可以選擇匹配除逗號以外的任何零個或多個字符,直到空格和逗號以外的字符:
str_extract_all(x, "([^\\s,](?:[^,]*[^\\s,])?)(?!.*\\1)")
在線查看正則運算式演示和R 演示。請注意,如果您的字串包含換行符,則需要在模式前加上(?s): str_extract_all(x, "(?s)([^\\s,](?:[^,]*[^\\s,])?)(?!.*\\1)")。
如果您需要使其不區分大小寫(例如Abb cd xy并且ABB cD Xy被認為是重復的),請添加i標志:(str_extract_all(x, "(?i)([^\\s,](?:[^,]*[^\\s,])?)(?!.*\\1)")或者str_extract_all(x, "(?si)([^\\s,](?:[^,]*[^\\s,])?)(?!.*\\1)")如果需要 DOTALL 行為)。
詳情:
([^\s,](?:[^,]*[^\s,])?)- 第 1 組:[^\s,]- 除空格和逗號以外的字符(?:[^,]*[^\s,])?- 一個可選的序列[^,]*- 除逗號外的零個或多個字符[^\s,]- 除空格和逗號以外的字符
(?!.*\1)- 如果有盡可能多的零個或多個字符,則匹配失敗的負前瞻,然后是 Group 1 值。
uj5u.com熱心網友回復:
只需添加lapply(..., str_trim)到您的代碼中:
library(stringr)
lapply(str_extract_all(x, "([^,] )(?!.*\\1)"), str_trim)
[[1]]
[1] "Anna & x"
[[2]]
[1] "Berta 222" "Alb"
[[3]]
[1] "Al Pacino"
[[4]]
[1] "Abb cd xy" "C123" "B"
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/358115.html
