恰好匹配一次出现而不是连续出现

问题描述 投票:0回答:4

我有一个文件名,其中包含从list.files(..., full.names = T)返回的目录路径。我想通过/拆分文件名来查找目录结构。我无法识别单次出现的/,例如

strsplit("C://dir1/dir2/txt.R", "/")
# [[1]]
# [1] "C:"    ""      "dir1"  "dir2"  "txt.R"

当我希望输出为:

[1] "C://"  "dir1"  "dir2"  "txt.R"

我正在看this answer似乎给出了一个正则表达式的答案,但是,当我尝试获得'文字'匹配时,我收到错误:

> strsplit("C://dir1/dir2/txt.R", "\/")
Error: '\/' is an unrecognized escape in character string starting ""\/"

事实上,该示例中的正则表达式在R中不起作用:

> grepl('([\w\/]+)\/amp(\/\w+[-\/]\w+\/?)', '/name/amp/test-123')
Error: '\w' is an unrecognized escape in character string starting "'([\w"
r regex
4个回答
2
投票

一种选择是匹配/SKIP的多个出现,同时分裂单个/或在/之后成功的单词边界

strsplit("C://dir1/dir2/txt.R", "[/]{2,}(*SKIP)(*F)|\\b[/]|(?<=[/])\\b", perl = TRUE)[[1]]
#[1] "C://"  "dir1"  "dir2"  "txt.R"

2
投票

试试这段代码:

strsplit("C://dir1/dir2/txt.R", "(?<=//)|(?<!/)/(?!/)", perl=TRUE)

See output here

说明:

  • (?<=//) - 找到一个位于//之前的位置
  • | - 或者
  • (?<!/)/(?!/) - 匹配一个/,既不是/,也不是/

Regex Demo


2
投票

吻,

strsplit("C://dir1/dir2/txt.R", "\\b/\\b|(?<=//)", perl = TRUE)[[1]]
# [1] "C://"  "dir1"  "dir2"  "txt.R"

2
投票

一种非常简单的匹配方法

x <- "C://dir1/dir2/txt.R"
regmatches(x, gregexpr("[^/]+(?://)?", x))
#  or with stringr
str_extract_all(x, "[^/]+(?://)?")
# [[1]]
# [1] "C://"  "dir1"  "dir2"  "txt.R"

参见regex demoR online demo

图案细节

  • [^/]+ - /以外的一个或多个字符
  • (?://)? - 两个/的可选序列。

请注意,如果您想忽略路径中的//并且只在开头抓取它们,您可以在可选组中添加^[[:alpha:]]://或lookbehind (?<=^[[:alpha:]]:)等替代方法:

regmatches(x, gregexpr("[^/]+(?:(?<=^[[:alpha:]]:)//)?", x, perl=TRUE))
# or
regmatches(x, gregexpr("^[[:alpha:]]://|[^/]+", x))

thisthat regex demo

© www.soinside.com 2019 - 2024. All rights reserved.