当前位置: 首页 > 知识库问答 >
问题:

R中的字符串操作:在多个位置删除特定模式,而不删除模式实例之间的文本

葛炯
2023-03-14

在R中,我正在尝试编写代码,以便对字符串模式进行任何调整。字符串的示例如下:

string <- "y ~ 1 + a + (b | c) + (d^2) + e + (1 | f) + g"

我只想删除包含“(,|,)”模式的部分,例如:

(b|c)和(1|f)

并留下:

"y ~ 1 + a + (d^2) + e + g"

请注意,字符可以更改值(例如,“b”可以变成“1”,“c”可以变成“预测器”),我希望代码仍然有效。字符串也不需要空格,它也可以是“y~1 a (b|c) (d^2) e (1|f) g” 或其空格/无空格的任意组合。字符的顺序也可以更改为“y~1 a (b|c) e (1|f) (d^2) g”。

我已经尝试使用基本R字符串操作函数(gsub和sub)通过使用模式的变体来搜索“(,|,)”的模式,例如:

"\\(.*\\|.*\\)"
"\\(.*\\|"
"\\(.+\\|.+\\)"
"\\|.+\\)"

以及许多用于查找此模式并将其替换为空白的 Stringr 函数。但是,同时使用基本 R 和字符串时,当我这样做时会发生什么,它会删除所有内容,例如:

gsub("\\(.*\\|.*\\)", "", string)

生产:

"y ~ 1 + a +  + g"

gsub("\\(.*\\|", "", string)

产生:

"y ~ 1 + a +  f) + g"

我还尝试使用str_locate函数,但在有效使用该函数时遇到了问题,因为有多组括号,并且我只希望实例的位置在它们之间带有“|”。

非常感谢任何帮助。

共有3个答案

东方俊材
2023-03-14

您可以将< code>gsub与下面的正则表达式一起使用,用空字符串替换匹配项。

"^\\([^|)]+\\|[^)]+\\) *\\+ ?| \\+? *\\([^|)]+\\|[^)]+\\)"

启动你的R引擎!

这个正则表达式很简单,因为它不包含任何环顾或更高级的正则表达式功能,因此它不需要 perl=TRUE。这会导致字符串:

(h|i) + y ~ 1 + a + (b | c) + (d^2) + e + (1 | f) + g +(j+k| m)

要成为1

y ~ 1 + a  + (d^2) + e  + g

交替的第一部分,

^\\([^|)]+\\|[^)]+\\) *\\+ ?

(..|..)开始字符串的情况下(在我的示例中,(h|i)

以下到regex101.com的链接对PCRE (PHP)引擎使用了等效的正则表达式。我把它包括进来,是为了让读者了解正则表达式的每个部分是如何工作的。(移动光标,可以看到有趣的细节神奇地出现在屏幕上。)

启动您的PCRE引擎!

1. 请注意,“a”和“e”后面有一个额外的空格。我认为这不是问题。

郜彦
2023-03-14

使用< code>gsub我们可以达到预期的效果。

model_texts <- c("y ~ 1 + a + (b | c) + (d^2) + e + (1 | f) + g",
"y~1+a+(b|c)+(d^2)+e+(1|f)+g" ,                 
"y~1+a+(b|c)+e+(1|f)+(d^2)+g" )   

pattern <- "\\(\\w ?\\| ?\\w ?\\) ?\\+ ?"

# tests

vapply(model_texts, function(x) gsub(pattern, "", x), "")

    "y ~ 1 + a + (d^2) + e + g" 
    "y~1+a+(d^2)+e+g" 
    "y~1+a+e+(d^2)+g" 



潘国源
2023-03-14

1) gsubfn定义一个函数,该函数根据输入是否有|返回空字符串或其输入,并运行< code>gsubfn。gsubfn类似于< code>gsub,只是替换字符串可以是一个函数,它将匹配项作为输入,并用函数的输出替换它。

library(gsubfn)

pick <- function(x) if (grepl("|", x, fixed = TRUE)) "" else trimws(x)
gsubfn("[+] *[(].*?[)]", pick, string, perl = TRUE)
## [1] "y ~ 1 + a  + (d^2) + e  + g"

2)base R将输入拆分为术语并去掉没有|的术语。然后使用重写将剩下的东西放回一起。

s <- trimws(grep("\\|", strsplit(string, "[~+]")[[1]], invert = TRUE, value = TRUE))
reformulate(format(s[-1]), s[1])
## y ~ 1 + a + (d^2) + e + g

3) getTerms这也只使用基数R,但首先将字符串转换为表示公式的表达式,并使用SO post中的< code>getTerms对其进行解析:R表达式中的求和项,然后像(2)中那样进行处理。

p <- parse(text = string)[[1]]
s <- grep("\\|", getTerms(p[[3]]), value = TRUE, invert = TRUE)
reformulate(s, p[[2]])
## y ~ 1 + a + (d^2) + e + g
 类似资料:
  • 我正在努力删除字符串中下划线前的子字符串。我想使用*(通配符)作为下划线可以变化之前的位: 结果应该是: 我也尝试过类似“^*”或“?”之类的东西但并没有真正奏效。

  • 在使用< code>bookdown的长段落中,我插入了许多图像。将段落组合成单个字符串(在数据框中)后,我想删除与插入图像相关的降价文本,但不删除这些插入图像之间的任何文本。这里有一个玩具的例子。 正则表达式不会在第一个闭括号处停止,它会一直持续到最后一个,并删除其间的“write to keep”。 我尝试在R中应用字符串操作:在多个位置删除特定模式,而不删除模式实例之间的文本,该模式使用和,

  • 问题内容: 我已经使用Python和Django建立了一个在线画廊。我刚刚开始添加编辑功能,从旋转开始。我使用sorl.thumbnail按需自动生成缩略图。 当我编辑原始文件时,我需要清理所有缩略图,以便生成新的缩略图。每个图片有三到四个(我在不同场合有不同的图片)。 我 可以 在文件变量中进行硬编码…但是这很混乱,如果我改变工作方式,则需要重新访问代码。 理想情况下,我想进行正则删除。用正则表

  • 我只需要删除特定字符之间的一些空格。这是我的数据: 我希望删除两个##标签之间的所有空白,这些空白除了数字之外没有任何其他分隔。我的数据应该如下所示: 我目前正在尝试在PHP中使用以下正则表达式来preg_replace这些空格,但是,我尝试过的所有内容都失败了。 调试演示

  • 我想通过以下方式删除字符串的最后一个后面的部分: 或者 到目前为止,我已经尝试过了(工作) 输出: 或 我是python的初学者,所以很好奇有没有其他方法可以做到这一点。

  • 问题内容: 我有这样的java字符串: 我想删除标签。我还有一些其他字符串,其中标签的长度更长,因此我想找到一种方法来删除“ <>”字符之间的所有内容,包括那些字符。 一种方法是使用将字符串与regEx进行比较的内置字符串方法,但是我不知道如何编写它们。 问题答案: 注意使用正则表达式时,解析HTML(由于其允许的复杂性),但是,对于“简单” HTML,以及简单的文本(文本没有字面建议或它)这将工