Шаблон регулярного выражения для извлечения данных из формата JSON, занимает слишком много времени, потому что не достаточно конкретен - PullRequest
2 голосов
/ 22 мая 2019

У меня проблема при попытке извлечь данные из структуры JSON. Я вижу шаблон, но не вижу четкого способа сделать его одновременно общим и эффективным.

Данные, которые я использую, соответствуют данным TMDB Box Office Prediction, полученным от Kaggle, и среди множества столбцов, некоторые из которых отформатированы в формате JSON. Поскольку я не вижу никакого значения в большинстве данных, которые вы можете извлечь из него, я на самом деле хотел получить просто список имен или имен каждого из этого JSON, поскольку каждый столбец JSON имеет атрибут с именем «name».

Я приведу несколько примеров, чтобы мы все могли немного понять, что я имею в виду:

[{'id': 34055, 'name': 'Pokémon Collection', 'poster_path': '/j5te0YNZAMXDBnsqTUDKIBEt8iu.jpg', 'backdrop_path': '/iGoYKA0TFfgSoZpG2u5viTJMGfK.jpg'}]
[{'id': 12, 'name': 'Adventure'}, {'id': 16, 'name': 'Animation'}, {'id': 10751, 'name': 'Family'}, {'id': 14, 'name': 'Fantasy'}]
[{'name': 'Woolner Brothers Pictures Inc.', 'id': 9233}]

Код, который я сделал и хотел, чтобы он был как можно более универсальным, выглядит следующим образом: он выбирает интересующие меня столбцы и ожидает получить имя и дать список имен, которые можно найти.

#trainSet is the data from the train.csv from the challenge
trainingNames <- as.data.frame(names(trainSet))
trainingNames1 <- trainingNames[c(2,4,12,13,16,20),]        
for (column in trainingNames1){
  for (i in 1:length(trainSet[[column]])) {
    keywords <- str_extract_all(toString(trainSet[[column]][[i]]), "'name': '(\\s*\\w+)+'")[[1]]
    keywords <- gsub("'", "", keywords)
    trainSet[[column]][i]  <- list(gsub("'name':", "", keywords))
    #print(trainSet[[column]][i] )
  }
}

Это регулярное выражение, если я проверяю в определенном случае, оно работает, но, поскольку в нем есть символы +, я понимаю, что это слишком много итераций по JSON и что в основном выполняется слишком много комбинаций. До этого регулярного выражения у меня было другое регулярное выражение, но главная проблема в том, что он не рассматривал случаи с «фразами», поэтому все, что будет более чем одним словом, не будет читать его. (например, имя: Властелин колец)

Я видел парня, который делает следующее, но он слишком специфичен для меня, и я хотел сэкономить время, чтобы не программировать шаблоны, которые предоставляют данные, поэтому даже это хорошее решение, я не нравится, потому что он привязан к определенному столбцу:

train$collection_name <- str_extract(train$belongs_to_collection, "(?<=name\\'\\:\\s{1}\\').+(?=\\'\\,\\s{1}\\'poster)")

Итак, что я хотел бы знать, так это то, можно ли сделать это подобным образом, я думаю, но, учитывая, что, например, должен заканчиваться " '" или другим шаблоном, который не следующий элемент JSON.

Может быть, я тоже неправильно к нему отношусь, поэтому я ценю любые комментарии / ориентации, которые вы мне предоставляете.

Спасибо!

1 Ответ

1 голос
/ 22 мая 2019

Если вам нужна группа, то:

'name': '(\\s*[^\\s']*)*'

еще

'name': '([^']*)'

Первое регулярное выражение будет быстрее, поскольку оно соответствует пробелам до следующего не пробела и без кавычек. Если вам не нужна группировка в том виде, в котором она была, вы можете использовать второе регулярное выражение. Это соответствует от первой цитаты до следующей цитаты, соответствуя всем не кавычкам.

...