[英]How can I extract the unmatched portion of a string in R with regular expressions?
我有一個非常凌亂的字符串向量。 這是一個例子:
library(tidyverse)
library(stringr)
strings <- tibble(
name = c("lorem 11:07:59 86136-1-sed",
"ipsum 14:35:57 S VARNAME-ut",
"dolor 10:37:53 1513 -2-perspiciatis",
"sit 10:48:25",
"amet 13:52:1365293-2-unde",
"consectetur 11:53:1 16018-2-omnis",
"adipiscing 11:19 17237-2-iste"
)
)
strings_out <- strings %>%
mutate(heads = str_extract(name, "^.*?\\s\\d{1,2}:\\d{1,2}:\\d{1,2}")) %>%
mutate(ends = str_replace(name, "^.*?\\s\\d{1,2}:\\d{1,2}:\\d{1,2}", ""))
strings_out[,2:3]
#> # A tibble: 7 x 2
#> heads ends
#> <chr> <chr>
#> 1 lorem 11:07:59 86136-1-sed
#> 2 ipsum 14:35:57 S VARNAME-ut
#> 3 dolor 10:37:53 1513 -2-perspiciatis
#> 4 sit 10:48:25
#> 5 amet 13:52:13 65293-2-unde
#> 6 consectetur 11:53:1 16018-2-omnis
#> 7 <NA> adipiscing 11:19 17237-2-iste
所以這里我有一些字符串,其中包含一些文本,然后是可能正確輸入或未正確輸入的時間,然后是更多文本。 我想在時間之后只提取字符串的末尾,但是它們沒有任何模式似乎與使用str_extract
的潛在正則表達式很好地對應。 我可以輕松匹配琴弦的前半部分,如heads
所示。 但是,我發現提取后半部分的唯一方法是使用帶有空字符串的str_replace
,如ends
所示。
我試圖在這個列表中包含我注意到的所有常見錯誤:時間后沒有關於連字符,間隔或字符串內容的模式,沒有保證時間和字符串所需的結束一半,時間丟失數字甚至是數字冒號。
我想做的是能夠使用str_extract
來獲得與str_replace
相近的東西。 關鍵的區別在於,對於這個正則表達式仍然不起作用的錯誤, str_extract
給了我一個易於過濾和手動修復的NA
,但是str_replace
只復制整個字符串,如第7行所示。
我懷疑我可以使用更多hacky方法來做到這一點,例如獲取所有NA
並在Excel或其他東西中手動修復,但我很驚訝我無法弄清楚如何返回字符串中不匹配的部分,盡管有一堆搜索並嘗試包含(^)
和[^]
不同正則表達式。 有任何想法嗎?
在一般情況下,你可能會想看看lookarounds ,但您的數據可能需要更多的結構對他們是有用的。
這是我寫的一個簡單的例子,我知道時間之后並不總是有空格:
library(tidyverse)
library(stringr)
strings <- tibble(
name = c("lorem 11:07:59 86136-1-sed",
"ipsum 14:35:57 S VARNAME-ut",
"dolor 10:37:53 1513 -2-perspiciatis",
"sit 10:48:25",
"amet 13:52:1365293-2-unde",
"consectetur 11:53:1 16018-2-omnis",
"adipiscing 11:19 17237-2-iste"
)
)
strings_out <- strings %>%
mutate(heads = str_extract(name, "^.*?\\s\\d{1,2}:\\d{1,2}:\\d{1,2}"),
ends = str_extract(name, "(?<=:\\d{1,2} )[\\s\\S]+$"))
strings_out[c(1,3)]
#> # A tibble: 7 x 2
#> name ends
#> <chr> <chr>
#> 1 lorem 11:07:59 86136-1-sed 86136-1-sed
#> 2 ipsum 14:35:57 S VARNAME-ut S VARNAME-ut
#> 3 dolor 10:37:53 1513 -2-perspiciatis 1513 -2-perspiciatis
#> 4 sit 10:48:25 <NA>
#> 5 amet 13:52:1365293-2-unde <NA>
#> 6 consectetur 11:53:1 16018-2-omnis 16018-2-omnis
#> 7 adipiscing 11:19 17237-2-iste 17237-2-iste
這里的問題是第5行。如果沒有更多結構,我們無法知道時間是13:52:13
還是13:52:1
,因為兩者都是其他字符串中的選項。 確定哪個是正確的不是可以用正則表達式解決的問題。
你也可以試試這個:
library(tidyverse)
library(stringr)
regex = "^\\w+\\s\\d{2}:\\d{2}:*\\d{0,2}"
strings %>%
mutate(head = str_extract(name, regex),
end = str_replace(name, paste0(regex, "\\s?"), ""),
end = str_replace(end, "^\\s*$", NA_character_))
結果:
# A tibble: 7 x 3
name head end
<chr> <chr> <chr>
1 lorem 11:07:59 86136-1-sed lorem 11:07:59 86136-1-sed
2 ipsum 14:35:57 S VARNAME-ut ipsum 14:35:57 S VARNAME-ut
3 dolor 10:37:53 1513 -2-perspiciatis dolor 10:37:53 1513 -2-perspiciatis
4 sit 10:48:25 sit 10:48:25 <NA>
5 amet 13:52:1365293-2-unde amet 13:52:13 65293-2-unde
6 consectetur 11:53:1 16018-2-omnis consectetur 11:53:1 16018-2-omnis
7 adipiscing 11:19 17237-2-iste adipiscing 11:19 17237-2-iste
注意:
我的解決方案適用於第5行,但在這種情況下,您必須決定是否要提取13:52:13
或13:52:1
。 這兩種情況都可以通過對正則表達式的簡單修改來完成,但正如@Zach所述,沒有自動方式。
只需一行即可獲得:
strings["rx"] <- str_match(strings$name, "\\d*:\\d*(?::\\d+)?(.*)")[,2]
strings
哪個收益率
# A tibble: 7 x 2
name rx
<chr> <chr>
1 lorem 11:07:59 86136-1-sed 86136-1-sed
2 ipsum 14:35:57 S VARNAME-ut S VARNAME-ut
3 dolor 10:37:53 1513 -2-perspiciatis 1513 -2-perspiciatis
4 sit 10:48:25
5 amet 13:52:1365293-2-unde -2-unde
6 consectetur 11:53:1 16018-2-omnis 16018-2-omnis
7 adipiscing 11:19 17237-2-iste 17237-2-iste
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.