Почему REGEXP_SUBSTR считывает определенные символы (‘L’ и ‘RD’) иначе, чем другие символы

#regexp-substr

#regexp-substr

Вопрос:

Я работаю с регулярным выражением, и некоторые символы дают неожиданные результаты

Я попробовал приведенный ниже код

 WITH DATA(str) AS(
   SELECT '437 E MERRIMACK ST APT 14' FROM dual UNION ALL
   SELECT '29 MARIAN RD # B' FROM dual UNION ALL
   SELECT '29 MARIAN RD' FROM dual UNION ALL
   SELECT '29 MARIAN ST' FROM dual UNION ALL
   SELECT '104 BEECH ST # 1L'    FROM dual UNION ALL
   SELECT 'w32 IRVING RD APT M'    FROM dual UNION ALL
   SELECT 'w32 IRVING RD # L'    FROM dual UNION ALL
   SELECT 'w32 IRVING AVE'    FROM dual UNION ALL
   SELECT '288 N MAIN ST APT 1-4'   FROM dual
)
SELECT 
str
,REGEXP_SUBSTR(str,  '[^(APT |FL |# |$)] $') APT 
FROM data;
  

строки 1, 2, 4, 6, 9 хороши, строки 3, 5, 7, 8 неправильно отображают APT. Кажется, есть какая-то проблема с ‘L’, ‘RD’ и ‘AVE’. Я ожидаю, что значение APT в # 3 будет равно нулю, значение APT в # 5 будет равно 1L, в # 7 будет L, а # 8 будет равно нулю.

 result# STR                         APT
1   437 E MERRIMACK ST APT 14        14
2   29 MARIAN RD # B                  B
3   29 MARIAN RD                     RD
4   29 MARIAN ST                     null
5   104 BEECH ST # 1L                null
6   w32 IRVING RD APT M              M
7   w32 IRVING RD # L                null
8   w32 IRVING AVE                VE 
9   288 N MAIN ST APT 1-4            1-4
  

Ответ №1:

Короче говоря, это не так, просто ваше регулярное выражение неверно. вы используете квадратные скобки, которые описывают класс символов (один символ). В вашем случае, НЕ open paren или A, или P, или T и т.д.

Попробуйте это, которое возвращает 2-ю группу, которая следует за последним вхождением строки, заканчивающейся пробелом, затем группу либо ‘APT’, либо знака фунта, затем еще один пробел, затем что угодно до конца строки (захватывая «что угодно» в группе). Другими словами, сохраните все после последнего APT или # и учтите, что APT:

 WITH DATA(id, str) AS (
   SELECT 1, '437 E MERRIMACK ST APT 14' FROM dual UNION ALL
   SELECT 2, '29 MARIAN RD # B'          FROM dual UNION ALL
   SELECT 3, '29 MARIAN RD'              FROM dual UNION ALL
   SELECT 4, '29 MARIAN ST'              FROM dual UNION ALL
   SELECT 5, '104 BEECH ST # 1L'         FROM dual UNION ALL
   SELECT 6, 'w32 IRVING RD APT M'       FROM dual UNION ALL
   SELECT 7, 'w32 IRVING RD # L'         FROM dual UNION ALL
   SELECT 8, 'w32 IRVING AVE'            FROM dual UNION ALL
   SELECT 9, '288 N MAIN ST APT 1-4'     FROM dual
)
SELECT id, str,
       REGEXP_SUBSTR(str,  '^.* (APT|#) (.*)$', 1, 1, null, 2) APT 
FROM data;

        ID STR                       APT                      
---------- ------------------------- -------------------------
         1 437 E MERRIMACK ST APT 14 14                       
         2 29 MARIAN RD # B          B                        
         3 29 MARIAN RD                                       
         4 29 MARIAN ST                                       
         5 104 BEECH ST # 1L         1L                       
         6 w32 IRVING RD APT M       M                        
         7 w32 IRVING RD # L         L                        
         8 w32 IRVING AVE                                     
         9 288 N MAIN ST APT 1-4     1-4                      

9 rows selected.
  

Комментарии:

1. Спасибо Gary_W!! Это сработало с одним незначительным изменением. Когда я скопировал код в точности, это не сработало — Мне пришлось убрать дополнительный пробел между звездочкой и открытой круглой скобкой в этом бите: ‘^.* (APT …’ — с этим небольшим изменением это работает!

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