2017-02-20 12 views
1

Названия курсов в университетах обычно разделяются на две разные части: «Отдел» и «Номер курса»Разбиение строк курса с помощью регулярного выражения

ENGLISH 101, например.

Моя цель - написать регулярное выражение, соответствующее шаблону, с группами, которые позволят мне указать, смотрю ли я на первую половину или вторую.

Проблема в том, что не все университеты используют один и тот же формат для этих вещей. Ниже приведены три тестовых примера, которые я имею для «Странных вещей», которые я встречал в других университетах.

1250-101 
ENGLISH101 
ENG|101-L 

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

SELECT REGEXP_SUBSTR('ENGLISH101','(^\D*)(\d*)',1,1,NULL,1) FROM DUAL; 
ENGLISH 
SELECT REGEXP_SUBSTR('ENGLISH101','(^\D*)(\d*)',1,1,NULL,2) FROM DUAL; 
101 
SELECT REGEXP_SUBSTR('ENG|101-L','^(\w*)[\|/, \\-](.*)',1,1,NULL,1) FROM DUAL; 
ENG 
SELECT REGEXP_SUBSTR('ENG|101-L','^(\w*)[\|/, \\-](.*)',1,1,NULL,2) FROM DUAL; 
101-L 

Так что это хорошо. Но я не знаю, как объединить, чтобы дать мне одно регулярное выражение, которое позволит мне получить АНГЛИЙСКИЙ (или что-то еще там) или 101 в зависимости от группировки. Или, может быть, группировка - это то, что вызывает эту головную боль?

В качестве альтернативы, регулярное выражение было неправильным способом сделать это все время, и должен ли я просто написать функцию для итерации по символам строк символом и разделить их сами? Это кажется неэффективным, но на данный момент я полагаю, что я должен задать вопрос.

Любой совет или понимание этого будут оценены.

ответ

0

В нижеследующем запросе должны быть указаны все записи, соответствующие трем описанным вами краям, и отделить первую половину от второй половины названия курса.

SELECT SUBSTR(col, 1, INSTR(col, '-') - 1) AS first_half, 
     SUBSTR(col, INSTR(col, '-') + 1) AS second_half 
FROM yourTable 
WHERE col LIKE '%-%' AND col NOT LIKE '%|%' 
UNION ALL 
SELECT SUBSTR(col, 1, INSTR(col, '|') - 1), 
     SUBSTR(col, INSTR(col, '|') + 1) 
FROM yourTable 
WHERE col LIKE '%|%' 
UNION ALL 
SELECT REGEXP_REPLACE(col, '[0-9]', ''), 
     REGEXP_REPLACE(col, '[A-Za-z]', '') 
FROM yourTable 
WHERE col NOT LIKE '%-%' AND col NOT LIKE '%|%' 

Объяснение:

Первый запрос в UNION целях этих имен конечно, имеющих тир, но не труба. В этом случае мы можем чисто разбить имя на основе тире. Второй запрос задает имена с помощью канала (который также может иметь тире). В этом случае мы хотим разделить на трубу. Наконец, третий запрос - это оставшийся случай, который является алфавитным названием курса, непосредственно предшествующим, без пробела, номером курса. Для этого я использовал REGEXP_REPLACE() для удаления либо числовых, либо алфавитных символов, чтобы оставить нас с первой и второй половинками.

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

+0

Итак, если я правильно понимаю, вы рекомендуете использовать множество операторов выбора (по одному для каждого случая использования), которые будут работать только в строках, отформатированных так, как они умеют разбирать, а затем объединяют эти результаты вместе получить один результирующий набор? – user3641364

+0

@ user3641364 Это точно моя стратегия. Дело в том, что для этого в одном регулярном выражении потребуются AFAIK, lookaheads или lookbehinds, которые в любом случае не поддерживаются. Поэтому использование более простых строковых функций может быть единственным способом. –

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

  • Нет связанных вопросов^_^