Замяна на екранирани двойни кавички с двойни кавички в R

Пиша някакъв html код в SQL база данни, използвайки RMySQL (но предполагам, че проблемът ми е по-скоро общ R въпрос, отколкото наистина свързан с SQL или RMySQL). Така че опитвам нещо подобно:

con <- RMySQL(...) # some connection    
html <- "<div style='text-align: center; font-family: Arial;'><span style='font-size: 14pt;'>Some text without any tricky symbols.</span></div>"    
    query <- c('INSERT INTO table (htmlfield) VALUES (\"', html, '"') 
    dbSendQuery(con,paste(query, collapse = ""))

Проблемът е, че поставянето на R ще замени двойните кавички в единични кавички (т.е. '"') с екранираната последователност \", т.е.:

> paste(query, collapse = "")
[1] "INSERT INTO table (htmlfield) VALUES (\"<div style='text-align: center; font-family: Arial;'><span style='font-size: 14pt;'>Some text without any tricky symbols.</span></div>\""

Ако променя единичните кавички във векторната заявка на двойни кавички и единичните кавички в html на двойни, тогава проблемът е от страната на символния низ html, тъй като тогава двойните кавички в html се заменят от екранираната последователност.

Кой е най-лесният начин да се справите със заместване на екранираните знаци?

Опитах gsub('\\\"','"',html), което не работи по предназначение и решенията, предложени в публикацията Игнориране на escape символи (обратни наклонени черти) в R низове, но не можах да го накарам да работи.

Благодаря за вниманието, Филип


person Philipp    schedule 15.01.2011    source източник
comment
Подозирам, че сте объркан между низа и неговото представяне. Започнете тук за просветление.   -  person hadley    schedule 15.01.2011
comment
След това проучете това   -  person hadley    schedule 15.01.2011
comment
paste не замества с \, методът print ги вмъква. Вашият пример трябва да работи. Каква е грешката, която получавате?   -  person VitoshKa    schedule 15.01.2011
comment
@VitoshKa Липсва завършващ ) в низа query, както споменах в отговора си, което, допускам, е причината да не работи. Подозирам, че тук се случват няколко неща, правописна грешка, водеща до грешка в SQL синтаксиса, и след това @Philipp забелязва скритото " в отпечатаното представяне и събира две и две заедно, за да излезе с пет.   -  person Gavin Simpson    schedule 15.01.2011


Отговори (3)


Виждам два проблема с това, което включихте във вашия Въпрос. Първото изглежда като печатна грешка. След:

html <- "<div style='text-align: center; font-family: Arial;'><span style='font-size: 14pt;'>Some text without any tricky symbols.</span></div>"   

Ти имаш:

query <- c('INSERT INTO table (htmlfield) VALUES (\"', html, '"')
                                                  ^^^^^^^^^^^^^^^

Забележете, че избягвате единия низ, но не и другия. Не е нужно да им бягате, но няма значение дали го правите. Вие също имахте предвид '")' за последния низ, който подозирам, че е истинският източник на грешката, която получавате. paste вместо c е по-полезно тук. Ако ги комбинирам, получаваме:

query <- paste('INSERT INTO table (htmlfield) VALUES ("', html, '")', sep = "")

които можем да използваме директно:

dbSendQuery(con, query)

Вторият проблем, който много хора правят, е да объркат печатното представяне на обект със самия обект. Ако отпечатаме query, виждаме това:

> query
[1] "INSERT INTO table (htmlfield) VALUES (\"<div style='text-align: center; font-family: Arial;'><span style='font-size: 14pt;'>Some text without any tricky symbols.</span></div>\")"

Отпечатаното представяне на низа винаги е затворено в "" двойни кавички и като такова вътрешното " трябва да бъде екранирано. Това, което искате да погледнете, е действителният низ. Можем да направим това с cat или writeLines - предпочитам последното, тъй като автоматично добавя "\n" към края на низа:

> writeLines(query)
INSERT INTO table (htmlfield) VALUES ("<div style='text-align: center; font-family: Arial;'><span style='font-size: 14pt;'>Some text without any tricky symbols.</span></div>")

Забележете как " сега не са екранирани. Това е SQL, който ще бъде изпълнен от сървъра на базата данни. Ако това е валиден SQL за вашата DB, тогава ще работи.

person Gavin Simpson    schedule 15.01.2011

Забравихте да избегнете самите обратни наклонени черти в низовете (мисля, че ще е така с повечето езици за програмиране, не съм сигурен дали същото важи и за R).

gsub("\\\"", "\"", html)
person orlp    schedule 15.01.2011
comment
Мисля, че твоята идея има идеален смисъл, R не... Може би има нещо общо с начина, по който R отпечатва низа. - person Philipp; 15.01.2011
comment
Какво ще видите, ако отпечатате този низ? "Replacing \\\" with \"!" - person orlp; 15.01.2011
comment
Мисля, че този начин няма да работи, тъй като print винаги ще избяга от ", а sub също се държи нещо подобно (или поне аз никога не съм успявал по този начин). cat и write биха работили, но това би било полезно само ако искате да запишете свързания низ във файл. - person daroczig; 15.01.2011
comment
WTF този език за програмиране R ли е? Различни последователности за бягство за различни контексти? Съмнявам се. - person orlp; 15.01.2011
comment
@nightcracker: cat и write не правят нищо с низове, само ги показват, докато print, gsub и други конвертират и форматират входа, затова кавичките са екранирани, както мисля, и не са във функциите, цитирани първо. - person daroczig; 15.01.2011
comment
Не, не разбирате какво представляват последователностите за бягство. Те са за компилатора/интерпретатора, за да разбере къде свършва и започва даден низ. """", това низ, съдържащ две кавички, или два празни низа? За това са последователностите за избягване: "\"\"". (Плюс други трудни знаци като нови редове) - person orlp; 15.01.2011
comment
@nightcracker: както написах cat и write не избягват низове, тъй като тези функции не са предназначени, докато print и други го правят, защото форматират входа. Вижте ?cat: „cat“ извършва много по-малко преобразуване от „print“. Например: cat няма да може да се справи със ситуациите, които сте описали по-горе. - person daroczig; 15.01.2011
comment
@daroczig бъркаш отпечатаното представяне на обект с обект. Помислете за print("\\\\\n") срещу cat("\\\\\n"). И в двете трябва да избегна обратните наклонени черти, но print ми показва вътрешното представяне, а cat действителния низ, който исках. Също така, print не прави нищо подобно на описаното от вас, той просто връща обекта (в този случай), cat и други преобразуват от R представянето в необходимия низ. - person Gavin Simpson; 15.01.2011
comment
@Gavin Simpson: Вече се опитах да му го обясня, но не успях :) - person orlp; 15.01.2011
comment
@Gavin, print не показва вътрешното представяне. nchar("\"") is 1. print` вмъква escape, който не е там. В същото време paste също не вмъква \ и по този начин оригиналният пример dbSendQuery(con,paste(query, collapse = "")) трябва да работи както желаете. - person VitoshKa; 15.01.2011
comment
@Gavin Simpson и @nightcracker: благодаря и на двамата, разбирам какво имате предвид. Това, което възнамерявах (но не уточнявайки добре, както направихте вие), че cat и write не поставят кавички около низове, докато показват данни като print, а също така екраниращите знаци се държат по друг начин (writeLines("\\") срещу print("\\")). Ето защо реших, че разликата във връщането/показването на низове между двете функции може да бъде интересна тук, тъй като в този въпрос поставянето на низ беше в центъра. Благодаря за пояснението, нямах предвид несъответствието вътрешно/външно (отпечатано) представяне. - person daroczig; 15.01.2011
comment
@Gavin Simpson – това, което все още не разбирам за това, че казвате, че print не прави нищо, което пиша, е: че ръководството (?cat) казва следното: „cat“ извършва много по-малко преобразуване от „print“. - person daroczig; 15.01.2011
comment
@VitoshKa се извинява, вътрешен беше лош избор на думи, трябваше да кажа печатен. - person Gavin Simpson; 15.01.2011
comment
@daroczig Може да е лош избор на думи от моя страна. print връща отпечатаната от R версия на низа (ефективно това, което човек въвежда, но с превключване към затваряне в "" и всички промени в низа, които изискват. cat ви показва низа, който сте възнамерявали, след като е отчетено цялото екраниране. Това е въпрос на гледна точка, предполагам, което прави повече от другото, тъй като обичам да cat и т.н. ми показва конвертирания низ, преобразуван от начина, по който трябва да го въведа в R и т.н. Но можете да видите това от другата страна. - person Gavin Simpson; 15.01.2011
comment
@Gavin Simpson: благодаря ви отново, разликата между двете функции вече е ясна. - person daroczig; 15.01.2011
comment
@Gavin, добра гледна точка! Отсега нататък трябва да правим разлика между печатни, вътрешни и входни представяния :) - person VitoshKa; 15.01.2011

Опитайте да поставите тази заявка:

query <- c('INSERT INTO table (htmlfield) VALUES (\'', html, '\'') 

Единствената промяна е в кавичките: \' вместо ".

И така като цяло:

html <- "<div style='text-align: center; font-family: Arial;'><span style='font-size: 14pt;'>Some text without any tricky symbols.</span></div>"    
query <- c('INSERT INTO table (htmlfield) VALUES (\'', html, '\'')
dbSendQuery(con, paste(query, collapse = ""))

Надявам се, че ще работи добре!

person daroczig    schedule 15.01.2011
comment
Това е просто избягване на проблема – истинският проблем; един за неразграничаване между отпечатаното представяне и действителното представяне на низа. - person Gavin Simpson; 15.01.2011