在 gsub 期间保留换行符并在字符串中有选择地缩进
Keep newline character and selectively indent in string during gsub
原标题:在gsub期间在字符串中保留换行符
有一个 ,我尝试将 JSON 转换为降价无序列表。快完成了,但是有一种模式我无法处理。如果字符串中包含 space、换行符、space 序列,则它将被视为列表项连字符。如果我尝试使用一些对换行符的引用来避免这种情况,那么一切都不会像我预期的那样起作用。
输入 JSON: https://gist.github.com/hermanp/381eaf9f2bf5f2b9cdf22f5295e73eb5
首选输出(两个space缩进)markdown:
- Info
- Python
- The Ultimate Python Beginner's Handbook
- Python Like You Mean It
- Automate the Boring Stuff with Python
- Data science Python notebooks
- Frontend
- CodePen
- JavaScript - Wikipedia
- CSS-Tricks
- Butterick’s Practical Typography
- Front-end Developer Handbook 2019
- Using Ethics In Web Design
- Client-Side Web Development
- Stack Overflow
- HUP
- Hope in Source
为了生成降价,我使用了以下两个脚本:
generate_md()
library(jsonlite)
generate_md <- function (jsonfile) {
bmarks_json_lite <- fromJSON(txt = jsonfile)
level1 <- bmarks_json_lite$children$children[[2]]
markdown_result <- recursive_func(level = level1)
return(markdown_result)
}
recursive_func()
recursive_func <- function (level) {
md_result <- character()
for (i in seq_len(nrow(level))) {
if (level[i, "type"] == "text/x-moz-place"){
md_title <- paste0("- ", level[i, "title"], "\n")
} else if (level[i, "type"] == "text/x-moz-place-container") {
md_title <- paste0("- ", level[i, "title"], "\n")
md_recurs <- recursive_func(level = level[i, "children"][[1]])
# >>>>> This is the problematic part. <<<<<
md_recurs <- gsub("-(?= )", " -", md_recurs, perl = T)
md_title <- paste0(md_title, md_recurs)
}
md_result <- paste0(md_result, md_title)
}
return(md_result)
}
通过这些函数,我可以实现以下目标(注意 JavaScript 维基百科条目中不必要的 spaces)。我想得到 - JavaScript - Wikipedia
而不是 - JavaScript - Wikipedia
。我希望这个例子代表带有连字符和缩进的不同场景,但这仍然只是我书签的一小部分。我想举一个最小的例子。
cat(generate_md(paste0("https://gist.githubusercontent.com/hermanp/",
"381eaf9f2bf5f2b9cdf22f5295e73eb5/raw/",
"76b74b2c3b5e34c2410e99a3f1b6ef06977b2ec7/",
"bookmarks-example-hyphen.json")))
# Output
- Info
- Python
- The Ultimate Python Beginner's Handbook
- Python Like You Mean It
- Automate the Boring Stuff with Python
- Data science Python notebooks
- Frontend
- CodePen
- JavaScript - Wikipedia
- CSS-Tricks
- Butterick’s Practical Typography
- Front-end Developer Handbook 2019
- Using Ethics In Web Design
- Client-Side Web Development
- Stack Overflow
- HUP
- Hope in Source
我修改了 recursive_func
中的 gsub
函数部分,如下所示,没有期望的输出:
md_recurs <- gsub("-(?= )", " -", md_recurs, perl = T) # Original
md_recurs <- gsub("(\n)?-(?= )", " -", md_recurs, perl = T) # No newlines
md_recurs <- gsub("(-)(?= )(?<=\n)?", " -", md_recurs, perl = T) # Same as Original
在 Google 上搜索 regex newline before char gsub site:whosebug.com
,我找不到这个问题的答案或提示。我也玩过regex101.com,但找不到正确的路径。
您可以使用
gsub("\w\h+-\h(*SKIP)(*F)|-(?=\h)", " -", x, perl=TRUE)
见regex demo。详情:
\w
- 一个字 char
\h+
- 一个或多个水平空格
-
- 一个 -
char
\h
- 水平空格
(*SKIP)(*F)
- 省略到目前为止匹配的文本,匹配失败并从失败的位置开始搜索
|
- 或
-
- 一个 -
字符
(?=\h)
- 紧跟水平空格。
在我仔细考虑了问题和字符串的结构并阅读了 lookbehind 之后,我终于想出了解决方案。
md_recurs
行需要修改为:
md_recurs <- gsub("(?<!(\w ))-(?= )", " -", md_recurs, perl = T)
这意味着 gsub()
pattern
参数必须修改为:
(?<!(\w ))-(?= )
这意味着:
- 替换一个连字符
-
(改为两个 space 和一个连字符 -
)
- 如果前面没有一个单词串和一个space
(?<!(\w ))
和
- 如果后面没有space
(?= )
.
原标题:在gsub期间在字符串中保留换行符
有一个
输入 JSON: https://gist.github.com/hermanp/381eaf9f2bf5f2b9cdf22f5295e73eb5
首选输出(两个space缩进)markdown:
- Info
- Python
- The Ultimate Python Beginner's Handbook
- Python Like You Mean It
- Automate the Boring Stuff with Python
- Data science Python notebooks
- Frontend
- CodePen
- JavaScript - Wikipedia
- CSS-Tricks
- Butterick’s Practical Typography
- Front-end Developer Handbook 2019
- Using Ethics In Web Design
- Client-Side Web Development
- Stack Overflow
- HUP
- Hope in Source
为了生成降价,我使用了以下两个脚本:
generate_md()
library(jsonlite)
generate_md <- function (jsonfile) {
bmarks_json_lite <- fromJSON(txt = jsonfile)
level1 <- bmarks_json_lite$children$children[[2]]
markdown_result <- recursive_func(level = level1)
return(markdown_result)
}
recursive_func()
recursive_func <- function (level) {
md_result <- character()
for (i in seq_len(nrow(level))) {
if (level[i, "type"] == "text/x-moz-place"){
md_title <- paste0("- ", level[i, "title"], "\n")
} else if (level[i, "type"] == "text/x-moz-place-container") {
md_title <- paste0("- ", level[i, "title"], "\n")
md_recurs <- recursive_func(level = level[i, "children"][[1]])
# >>>>> This is the problematic part. <<<<<
md_recurs <- gsub("-(?= )", " -", md_recurs, perl = T)
md_title <- paste0(md_title, md_recurs)
}
md_result <- paste0(md_result, md_title)
}
return(md_result)
}
通过这些函数,我可以实现以下目标(注意 JavaScript 维基百科条目中不必要的 spaces)。我想得到 - JavaScript - Wikipedia
而不是 - JavaScript - Wikipedia
。我希望这个例子代表带有连字符和缩进的不同场景,但这仍然只是我书签的一小部分。我想举一个最小的例子。
cat(generate_md(paste0("https://gist.githubusercontent.com/hermanp/",
"381eaf9f2bf5f2b9cdf22f5295e73eb5/raw/",
"76b74b2c3b5e34c2410e99a3f1b6ef06977b2ec7/",
"bookmarks-example-hyphen.json")))
# Output
- Info
- Python
- The Ultimate Python Beginner's Handbook
- Python Like You Mean It
- Automate the Boring Stuff with Python
- Data science Python notebooks
- Frontend
- CodePen
- JavaScript - Wikipedia
- CSS-Tricks
- Butterick’s Practical Typography
- Front-end Developer Handbook 2019
- Using Ethics In Web Design
- Client-Side Web Development
- Stack Overflow
- HUP
- Hope in Source
我修改了 recursive_func
中的 gsub
函数部分,如下所示,没有期望的输出:
md_recurs <- gsub("-(?= )", " -", md_recurs, perl = T) # Original
md_recurs <- gsub("(\n)?-(?= )", " -", md_recurs, perl = T) # No newlines
md_recurs <- gsub("(-)(?= )(?<=\n)?", " -", md_recurs, perl = T) # Same as Original
在 Google 上搜索 regex newline before char gsub site:whosebug.com
,我找不到这个问题的答案或提示。我也玩过regex101.com,但找不到正确的路径。
您可以使用
gsub("\w\h+-\h(*SKIP)(*F)|-(?=\h)", " -", x, perl=TRUE)
见regex demo。详情:
\w
- 一个字 char\h+
- 一个或多个水平空格-
- 一个-
char\h
- 水平空格(*SKIP)(*F)
- 省略到目前为止匹配的文本,匹配失败并从失败的位置开始搜索|
- 或-
- 一个-
字符(?=\h)
- 紧跟水平空格。
在我仔细考虑了问题和字符串的结构并阅读了 lookbehind 之后,我终于想出了解决方案。
md_recurs
行需要修改为:
md_recurs <- gsub("(?<!(\w ))-(?= )", " -", md_recurs, perl = T)
这意味着 gsub()
pattern
参数必须修改为:
(?<!(\w ))-(?= )
这意味着:
- 替换一个连字符
-
(改为两个 space 和一个连字符-
) - 如果前面没有一个单词串和一个space
(?<!(\w ))
和 - 如果后面没有space
(?= )
.