Извлечение символов в середине строки (может быть, с регулярным выражением?) В R
Я борюсь с регулярным выражением, и я не могу понять это.
У меня есть база данных ставок, извлеченная из last.fm (www.lastfm.com). Этот файл представляет собой TXT-файл, в котором каждый столбец в каждой строке разделен символом "," (запятая) размером более 1,7 ГБ, и есть некоторые символы, которые мешают чтению в R. До сих пор мне удавалось понять, где все идет не так, и Основная проблема заключается в "(кавычки) внутри других кавычек.
Чтобы пояснить, вот пример файла.txt, когда применяется readLines.
[1] "user,\"Method Man & Redman\",\"Da Rockwilder\",0,2012,2,10,8,0,41"
[2] "user,\"Method Man & Redman\",\"Y.O.U.\",0,2012,2,10,7,56,25"
[3] "user,\"Method Man & Redman\",\"Blackout\",0,2012,2,10,7,51,53"
[4] "user,\"Chuckie\",\"Who Is Ready To Jump (Club Mix)\",0,2012,2,10,7,40,12"
[5] "user,\"Opgezwolle\",\"Volle Kracht\",0,2012,2,10,7,36,31"
[6] "user,\"Opgezwolle\",\"Ut Is Wat Het Is\",0,2012,2,10,7,33,25"
В основном это становится фреймом данных с 10 столбцами: имя пользователя, "Исполнитель", "Трек", "Любимый" (0/1), год, месяц, день, час, минута, секунда.
Приведенный выше пример можно легко прочитать без проблем, но у меня возникают проблемы, когда происходит что-то подобное:
[1] "user,\"Fall Out Boy\",\"\"The Take Over, The Breaks Over\"\",0,2010,4,17,7,11,37"
[2] "user,\"Gare du Nord\",\"I Want Love 12\" Remix\",0,2011,6,12,19,32,33"
В первом случае, из-за двойных кавычек, запятая в названии трека превращает это в два разных столбца, и вместо 10 столбцов я получаю 11 столбцов. Во втором случае "12" оставляет строку "открытой" и останавливается только до тех пор, пока не найдет аналогичный случай. Когда это происходит, я теряю несколько строк фрейма данных.
Что я хочу в качестве решения? Я хочу удалить все "(кавычки), кроме тех, которые окружают имя исполнителя и название трека.
Выходные данные: выходные данные будут иметь в общей сложности четыре (4) " (кавычки) в каждой строке. "Artist"и"Track Name". Таким образом, выходные данные для этих двух строк, которые вызывают у меня проблему, будут:
[1] "user,\"Fall Out Boy\",\"The Take Over, The Breaks Over\",0,2010,4,17,7,11,37"
[2] "user,\"Gare du Nord\",\"I Want Love 12 Remix\",0,2011,6,12,19,32,33"
Я пытался использовать Regex с gsub и gstring, но я не могу заставить его извлечь только "лишние метки".
Если это слишком сложно, то что-то, что извлекало бы все "кроме первых 3 (кавычки вокруг имени исполнителя и первой кавычки вокруг названия дорожки) и последней (кавычка в конце имени дорожки), может работать для большинства случаев (и я бы сделал все остальное вручную). Я предполагаю, что ни одно имя исполнителя не содержит кавычек.
Буду признателен за любую помощь, и если вам нужны дополнительные объяснения или данные, пожалуйста, дайте мне знать.
2 ответа
Используйте негативные обходные пути, чтобы удалить все \"
которым не предшествуют и не следуют запятые.
(?<!,)\\"(?!,)
> x <- c('user,\"Fall Out Boy\",\"\"The Take Over, The Breaks Over\"\",0,2010,4,17,7,11,37', 'user,\"Gare du Nord\",\"I Want Love 12\" Remix\",0,2011,6,12,19,32,33')
> gsub("(?<!,)\\\"(?!,)", "", x, perl=T)
[1] "user,\"Fall Out Boy\",\"The Take Over, The Breaks Over\",0,2010,4,17,7,11,37"
[2] "user,\"Gare du Nord\",\"I Want Love 12 Remix\",0,2011,6,12,19,32,33"
Обратите внимание, что в аргументе шаблона должна быть дополнительная обратная косая черта, поскольку обратные косые черты являются управляющими операторами как в R, так и в regex-engine.
Классы символов с буквенно-цифровыми и двойными кавычками и обратными ссылками могут сделать это:
gsub("([ 0-9a-zA-Z\"])(\\\")([ 0-9a-zA-Z\"])", "\\1\\3",test)
[1] "user,\"Fall Out Boy\",\"The Take Over, The Breaks Over\",0,2010,4,17,7,11,37"
[2] "user,\"Gare du Nord\",\"I Want Love 12 Remix\",0,2011,6,12,19,32,33"
Могли бы также рассмотреть:
gsub("([ [:alpha:][:digit:]\"])(\\\")([ [:alpha:][:digit:]\"\"])",
"\\1\\3", test)
В основном удаляется любая двойная кавычка, которая с обеих сторон окружена классом, в котором нет запятой. Сломался бы, если бы между вашими кавычками и правильными разделяющими знаками были пробелы. Страница? Regex описывает ваши варианты использования классов символов. Круглые скобки - это разделители для обратных ссылок: первый '\\1'
и относится к символам, сопоставляемым классом символов в первых парных скобках: ([ [:alpha:][:digit:]\"])
, Опуская среднюю обратную ссылку в аргументе замены, удаляются совпадающие двойные кавычки.