R语言 提取两个字符串之间不同的字符

wpcxdonn  于 12个月前  发布在  其他
关注(0)|答案(9)|浏览(83)

我使用adist来计算两个字符串之间不同的字符数:

a <- "Happy day"
b <- "Tappy Pay"
adist(a,b) # result 2

字符串
现在我想提取那些不同的字符。在我的例子中,我想得到字符串"Hd"(或"TP",无所谓)。
我试着在adistagrepstringi中查找,但什么也没找到。

yqkkidmi

yqkkidmi1#

您可以使用以下操作顺序:

  • 使用strsplit()拆分字符串。
  • 使用setdiff()比较元素
  • 在一个reducing function中

试试这个:

Reduce(setdiff, strsplit(c(a, b), split = ""))
[1] "H" "d"

字符串

cxfofazt

cxfofazt2#

拆分成字母,并将其差值作为集合:

> setdiff(strsplit(a,"")[[1]],strsplit(b,"")[[1]])
[1] "H" "d"

字符串

hzbexzde

hzbexzde3#

这并不值得骄傲,但它似乎做的工作:

sapply(setdiff(utf8ToInt(a), utf8ToInt(b)), intToUtf8)

字符串
结果如下:

[1] "H" "d"

uurv41yg

uurv41yg4#

只要ab具有相同的长度,我们就可以这样做:

s.a <- strsplit(a, "")[[1]]
s.b <- strsplit(b, "")[[1]]
paste(s.a[s.a != s.b], collapse = "")

字符串
给出:

[1] "Hd"


从代码的清晰度来看,这似乎很简单,并且似乎与这里提供的最快的解决方案相关联,尽管我认为我更喜欢f3

f1 <- function(a, b)
  paste(setdiff(strsplit(a,"")[[1]],strsplit(b,"")[[1]]), collapse = "")

f2 <- function(a, b)
  paste(sapply(setdiff(utf8ToInt(a), utf8ToInt(b)), intToUtf8), collapse = "")

f3 <- function(a, b) 
  paste(Reduce(setdiff, strsplit(c(a, b), split = "")), collapse = "")

f4 <- function(a, b) {
  s.a <- strsplit(a, "")[[1]]
  s.b <- strsplit(b, "")[[1]]
  paste(s.a[s.a != s.b], collapse = "")
}

a <- "Happy day"
b <- "Tappy Pay"

library(rbenchmark)
benchmark(f1, f2, f3, f4, replications = 10000, order = "relative")[1:4]


在我的笔记本电脑上进行了一次新的会话:

test replications elapsed relative
3   f3        10000    0.07    1.000
4   f4        10000    0.07    1.000
1   f1        10000    0.09    1.286
2   f2        10000    0.10    1.429


我假设不同之处一定是在相应的字符位置上。你可能想澄清这是否是意图。

np8igboo

np8igboo5#

您可以使用其中一个变量作为正则表达式字符类,并从另一个变量中取出gsub

gsub(paste0("[",a,"]"),"",b)
[1] "TP"
gsub(paste0("[",b,"]"),"",a)
[1] "Hd"

字符串

vhmi4jdf

vhmi4jdf6#

下面的函数可能是解决此类问题的更好选择。

list.string.diff <- function(a, b, exclude = c("-", "?"), ignore.case = TRUE, show.excluded = FALSE)
{
if(nchar(a)!=nchar(b)) stop("Lengths of input strings differ. Please check your input.")
if(ignore.case)
{
a <- toupper(a)
b <- toupper(b)
}
split_seqs <- strsplit(c(a, b), split = "")
only.diff <- (split_seqs[[1]] != split_seqs[[2]])
only.diff[
(split_seqs[[1]] %in% exclude) |
(split_seqs[[2]] %in% exclude)
] <- NA
diff.info<-data.frame(which(is.na(only.diff)|only.diff),
split_seqs[[1]][only.diff],split_seqs[[2]][only.diff])
names(diff.info)<-c("position","poly.seq.a","poly.seq.b")
if(!show.excluded) diff.info<-na.omit(diff.info)
diff.info

字符串
https://www.r-bloggers.com/extract-different-characters-between-two-strings-of-equal-length/
然后你就可以跑了

list.string.diff(a, b)


来获得差异。

rkttyhzu

rkttyhzu7#

我已经能够用下面的代码得到两个字符串之间的差异:

library(rmarkdown)
library(stringr)
library(diffr)
library(pagedown)
library(RDCOMClient)

print_Visual_File_Difference_Between_Text_To_Html <- function(text1, text2, output_Filepath)
{
  file1 <- tempfile(fileext = ".txt")
  writeLines(text1, con = file1)
  file2 <-  paste0(tempfile(), ".txt")
  writeLines(text2, con = file2)
  rmd_File <- tempfile(fileext = ".rmd")
  command_Diff <- paste0("diffr(", paste0("'", file1, "'"), ", ", paste0("'", file2, "'"), ", ", "before = 'Text 1', after = 'Text 2')")
  command_Diff <- str_replace_all(string = command_Diff, pattern = "\\\\", replacement = "/")

  rmd_Text <- c("---", "title: 'Text comparison between files'", "output: html_document",
                "---", "```{r file comparison, echo = FALSE}", "library(diffr)", command_Diff, "```")

  writeLines(rmd_Text, con = rmd_File)
  rmarkdown::render(rmd_File)
  rmd_Html  <- stringr::str_replace(string = rmd_File, pattern = "\\.rmd", replacement = "\\.html")
  file.copy(from = rmd_Html, to = output_Filepath)
}

setwd("C:\\")
text1 <- "Mon nom est Emmanuel Hamel. Mon adresse est le 324 jorge 1. Mon numéro de tel est 591-452-4000"
text2 <- "Mon nom est Emmanuel Hamel. Mon adresse est le xxxxxxx. Mon numéro de tel est xxxxxxx"
print_Visual_File_Difference_Between_Text_To_Html(text1, text2, output_Filepath = "comparaison.html")

IEApp <- COMCreate("InternetExplorer.Application")
IEApp[['Visible']] <- TRUE
IEApp$Navigate2("C:\\comparaison.html")
doc <- IEApp$Document()
web_Obj_Char_Delete <- doc$getElementsByClassName("char-delete")
web_Obj_Char_Insert <- doc$getElementsByClassName("char-insert")

> web_Obj_Char_Delete$Item(0)$innerText()
[1] "324 jorge 1"
> web_Obj_Char_Insert$Item(0)$innerText()
[1] "xxxxxxx"
> web_Obj_Char_Delete$Item(1)$innerText()
[1] "591-452-4000"
> web_Obj_Char_Insert$Item(1)$innerText()
[1] "xxxxxxx"

字符串
我使用Internet Explorer在本地模式下读取HTML文件。也可以使用Selenium。请参阅:使用RSelenium打开本地HTML文件

zbsbpyhn

zbsbpyhn8#

以下是基于Word软件的另一种方法:

library(RDCOMClient)

path_To_File1 <- "C\\...\\file_1.docx"
path_To_File2 <- "C\\...\\file_2.docx"
path_To_File3 <- "C\\...\\file_3.docx"

text1 <- "Mon nom est Emmanuel Hamel. Mon adresse est le 324 jorge 1. Mon numéro de tel est 591-452-4000"
text2 <- "Mon nom est Emmanuel Hamel. Mon adresse est le xxxxxxx. Mon numéro de tel est xxxxxxx"

wordApp <- COMCreate("Word.Application")
wordApp[["Visible"]] <- TRUE
doc1 <- wordApp[["Documents"]]$Open(normalizePath(path_To_File1))
doc1$Content()$InsertAfter(text = text1)
doc2 <- wordApp[["Documents"]]$Open(normalizePath(path_To_File2))
doc2$Content()$InsertAfter(text = text2)
doc3 <- wordApp[["Application"]]$CompareDocuments(OriginalDocument = doc1, RevisedDocument = doc2)
nb_Revisions <- doc3$Revisions()$Count()

for(i in 1 : nb_Revisions)
{
  print(doc3$Revisions()$Item(i)$Range()$Text())
}

[1] "324 jorge 1"
[1] "xxxxxxx"
[1] "591-452-4000"
[1] "xxxxxxx"

字符串

k5hmc34c

k5hmc34c9#

以下是另一个基于chatgpt的答案:

library(chatgpt)
library(stringr)
question <- "What caracters differ between the text_1 and text_2. Only provide the caracter difference in the answer. 
             text_1 : Mon nom est Emmanuel Hamel. Mon adresse est le 324 jorge 1. Mon numéro de tel est 591-452-4000
             text_2 : Mon nom est Emmanuel Hamel. Mon adresse est le xxxxxxx. Mon numéro de tel est xxxxxxx"

Sys.setenv(OPENAI_API_KEY = "xxx")
chatgpt::reset_chat_session()
text <- ask_chatgpt(question)
text_Extracted <- unlist(stringr::str_extract_all(text, "(:.*\\(text_\\d\\))|(vs.*\\(text_\\d\\))"))
unlist(stringr::str_split(text_Extracted, "vs"))

[1] ": \"324 jorge 1\" (text_1) "  " \"xxxxxxx\" (text_2)" ": \"591-452-4000\" (text_1) " " \"xxxxxxx\" (text_2)"

字符串

相关问题