2013-11-06 2 views
0

Я пытаюсь написать регулярное выражение, соответствующий шаблон которого исключает определенные строки. Он должен удалять все вхождения только числа и буквенно-цифровых строк, а также удалять все знаки препинания, но содержать определенные значимые строки (911, K-12, K9, E-COMMERCE и т. Д.).Регулярное выражение с отрицательным lookahead

Я решил, что мне нужно использовать отрицательный lookahead и указать, что нужно пропустить. Соответствующий шаблон работает почти по мере необходимости, но есть пара, для которой она не работает. Ниже приведен код и результаты сопоставления. Есть пара, для которой я указал, что должно быть результатом. Те, которые я не могу понять, это строка с комбинацией пунктуаций, чисел и символов. Любая помощь приветствуется. Благодарю.

blah <- c('ASDF911 2346', 'E-COMMERCE', 'AMAZON E-COMMERCE', 'K-12 89752 911', '65426 -', 'TEACHERK-12', 'K9 OFFICER', 'WORK - K-9564', 'DEVELOPER C++', ' C+ C +5', 'DEFAULT - 456') 
gsub('(^|)(?!(911|E[-]COMMERCE|K[-]12|C[+]{1,2}))([[:punct:]]|[0-9]+|([0-9]+[A-Z]+|[A-Z]+[0-9]+)[0-9A-Z]*)', ' ', blah, perl = TRUE) 

" "      # OK 
"E-COMMERCE"   # OK 
"AMAZON E-COMMERCE"  # OK 
"K-12 911"    # OK 
" "     # OK 
"TEACHERK-12"   # this should be " " 
"K9 OFFICER"   # OK 
"WORK K-9564"   # this should be "WORK " 
"DEVELOPER C++"   # OK 
" C+ C 5"    # this should be " C+ C " 
"DEFAULT "    # OK 
+1

У меня трудное время следующей вашей логике здесь. Почему '' C + C 5 "' не '" C + C "и' "TEACHERK-12" 'не' 'TEACHERK" '? –

+0

@TylerRinker Я согласен с вашей логикой для «C + C» и изменил свой вопрос. Что касается «TEACHERK-12», я консервативен. Это может быть «ABCK-12», и тогда это было бы бессмысленно, чего я не знал бы в большом наборе данных, который я не могу прочитать. На данный момент я считаю буквенно-цифровые строки с/или без/пунктуации бессмысленными. – vatodorov

ответ

1

Легче будет соответствовать как, а затем заменить на белый список ключевых слов:

gsub('(?:\\b(911\\b|E-COMMERCE\\b|K-12\\b|C\\b[+]{0,2})|[[:punct:]]|[A-Z-]*[0-9][A-Z0-9-]*)', '\\1', blah, perl = TRUE) 

Выход:

" " 
"E-COMMERCE" 
"AMAZON E-COMMERCE" 
"K-12 911" 
" " 
"" 
" OFFICER" # Should this really be "K9 OFFICER"? 
"WORK " 
"DEVELOPER C++" 
" C+ C " 
"DEFAULT " 
  • \b является границей слова. Он соответствует пустой строке на краях последовательности словных символов ([A-Za-z0-9_]). Это оптимизированная версия (?<!\w)(?=\w)|(?<=\w)(?!\w).
  • [A-Z-]*[0-9][A-Z0-9-]* соответствует строкам букв, цифр и тире, по крайней мере с одной цифрой.

http://ideone.com/E3TUU5

+0

Отлично работает! Благодарю. Да, это должно быть «K9 OFFICER», но я могу добавить это сам в код, который вы опубликовали. – vatodorov

Смежные вопросы