Захватить всю подстроку с помощью регулярного выражения, если есть совпадение по числу

Мне не удалось найти ответ на этот конкретный вопрос, я использую R для очистки некоторых данных опроса.

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

questions <- c(
"1 question 1 what do you think?",
"1.a. question 1a further details on what you think",
"Please explain",
"2 question 2 what is your motivation",
"2.a. further details",
"2.b. even further details",
"Please explain")

Я хочу извлечь подстроки, содержащие числа, и не возвращать результатов, если такого совпадения нет. Желаемый результат (используя R)

"1"
"1.a."
NA
"2"
"2.a."
"2.b."
NA

Я знаю, что могу записать первое число, используя

 stri_extract_first_regex(questions, "[0-9]+")

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

Вы имеете в виду как \d+(?:\.[a-z]\.)?

The fourth bird 31.10.2018 12:08
0
1
63
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это может сработать:

hasnumber <- grepl("[0-9]+",questions)
firstspaces <- sapply(gregexpr(" ", questions), function(x) x[[1]])
res <- ifelse(hasnumber, substr(questions,1,firstspaces-1), NA)
> res
[1] "1"    "1.a." NA     "2"    "2.a." "2.b." NA    

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

Вы можете использовать

questions <- sub("^(\\d+(?:\\.[a-z0-9]+)*\\.?).*|.*", "\\1", questions)
questions[questions==""] <- NA
questions
# => [1] "1"    "1.a." NA     "2"    "2.a." "2.b." NA

Соответствует ^(\\d+(?:\\.[a-z0-9]+)*\\.?).*|.*

  • ^ - начало строки
  • (\\d+(?:\\.[a-z0-9]+)*) - Группа захвата 1:
    • \\d+ - 1+ цифр
    • (?:\\.[a-z0-9]+)* - 0 или более повторений
      • \\. - точка
      • [a-z0-9]+ - 1 или несколько строчных букв или цифр ASCII
    • \\.? - необязательная точка
  • .* - любые символы 0+ до конца строки
  • | - или
  • .* - целая строка.

Заменяет содержимое группы 1. Если вторая альтернатива совпадает, результатом является пустая строка, questions[questions==""] <- NA заменяет эти элементы на NA.

Ответ принят как подходящий

В качестве примера данных вы можете использовать:

[0-9]+(?:\.[a-z]\.)?

Это будет соответствовать:

  • [0-9]+ Соответствие 1+ цифрам
  • (?: Группа без захвата
    • \.[a-z]\. Сопоставление точки, символа нижнего регистра и точки
  • )? Закройте группу без захвата и сделайте ее необязательной

Например:

questions <- c(
"1 question 1 what do you think?",
"1.a. question 1a further details on what you think",
"Please explain",
"2 question 2 what is your motivation",
"2.a. further details",
"2.b. even further details",
"Please explain")

print(stri_extract_first_regex(questions, "[0-9]+(?:\\.[a-z]\\.)?"))

# [1] "1"    "1.a." NA     "2"    "2.a." "2.b." NA 

Здравствуйте, просто вопрос, есть ли способ изменить это, чтобы смотреть только на начало строки (скажем, первые 5 символов)? У меня проблемы с некоторыми вопросами, у которых нет числового индикатора (например, «Пожалуйста, объясните» в моем примере), внутри которых есть числа, которые на самом деле не являются номером вопроса.

John Hekman 31.10.2018 16:38

@JohnHekman Вы можете использовать якорь для подтверждения начала строки ^[0-9]+(?:\\.[a-z]\\.)? См. демонстрация

The fourth bird 31.10.2018 16:41

Другие вопросы по теме