Получить второе совпадение из результатов regexp_matches - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть столбец name, который выглядит следующим образом:

'1234567 - 7654321 - some - more - text'

Мне нужно получить строку "7654321". Я застрял со следующим:

SELECT regexp_matches('1234567 - 7654321 - some - more - text', '\d+', 'g');

regexp_matches
----------------
{1234567}
{7654321}

(2 rows)

Как мне то, что я хочу? Может быть, есть лучший вариант, чем regexp_matches - с удовольствием рассмотрим. Thx!

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

regexp_matches() возвращает таблицу, так что вы можете использовать ее в предложении from вместе с опцией with ordinality:

SELECT t.value
from regexp_matches('1234567 - 7654321 - some - more - text', '\d+', 'g') with ordinality as t(value,idx)
where t.idx = 2;

Обратите внимание, что value по-прежнему является массивом, чтобы получить фактический элемент массива, который вы можете использовать:

SELECT t.value[1]
from regexp_matches('1234567 - 7654321 - some - more - text', '\d+', 'g') with ordinality as t(value,idx)
where t.idx = 2;
0 голосов
/ 05 сентября 2018

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

SELECT REGEXP_REPLACE('1234567 - 7654321 - some - more - text', '^\d+[^\d]+(\d+).*$', '\1');

Выход

7654321

Это регулярное выражение ищет строку, начинающуюся с некоторого количества цифр (^\d+), за которыми следуют несколько нецифровых символов ([^\d]+), а затем другая группа цифр ((\d+)), за которой следует некоторое количество символов до конец строки (.*$). () вокруг второй группы цифровых символов делает эту группу захвата, к которой мы затем можем обратиться в строке замены с \1. Поскольку REGEXP_REPLACE заменяет только те части строки, которые соответствуют регулярному выражению, необходимо иметь регулярное выражение, совпадающее с всей строкой, чтобы заменить ее только требуемыми данными.

Обновление

Если перед первым набором цифр есть потенциально символы, вы должны изменить регулярное выражение на

^[^\d]*\d+[^\d]+(\d+).*$

Обновление 2

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

^[^\d]*(?:\d+[^\d]+)?(\d+).*$

Это делает сопоставление для первого набора цифр необязательным, так что, если оно не существует (то есть существует только один набор цифр), регулярное выражение все равно будет совпадать. Используя не захватывающую группу (добавляя ?: в начало группы, нам не нужно менять строку замены с \1. Обновлено SQLFiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...