Извлечь TextString между вторым и третьим дефисом - PullRequest
0 голосов
/ 03 мая 2020

Я пытаюсь извлечь некоторую информацию из строки в одном из моих столбцов с помощью RegEx.

Мне нужно определить второй столбец, равный тому, что находится между 2-м и 3-м появлением дефиса в моем первом столбце.

После долгих поисков мне удалось продвинуться так далеко:

IFNULL(SAFE.REGEXP_EXTRACT(Final.CampaignName, r"(?:\w+\s+-\s+){2}(\w+)\s+-"), "Other") AS CampaignCategory

Пример того, как может выглядеть строка в Final.CampaignName:

S - Апельсины - Бар - Яблоки

S - Яблоки - Foo Bar - Апельсины - Бананы

S - Яблоки - Bar

My Regex вернет значение только в том случае, если между 2-м и 3-м дефисом есть 1 слово, но мне нужно вернуть весь текст (минус начальные и конечные пробелы).

Кто-нибудь может направить меня в правильном направлении к этому?

Спасибо!

Ответы [ 5 ]

2 голосов
/ 03 мая 2020

Если механизм регулярных выражений поддерживает \K (свободно, забудьте, что все совпадения до сих пор), можно использовать следующее регулярное выражение для сопоставления текста между вторым и третьим дефисом.

^(?:[^-]+-){2}\K[^-]+(?=-)

Обратите внимание, что это регулярное выражение не содержит группу захвата.

Демо

Это не соответствует Bar в третьем примере, потому что есть только два дефиса. Чтобы сопоставить Bar, просто удалите заглядывание (?=-).

Механизм регулярных выражений выполняет следующие операции.

^           match beginning of line
(?:[^-]+-)  match 1+ chars other than '-' followed by '-'
            in a non-capture group
{2}         execute non-capture group twice
\K          discard everything matched so far (reset the starting
            point of the reported match)
[^-]+       match 1+ chars other than '-'
(?=-)       match '-' in a positive lookahead

Если [^-] не соответствует символу новой строки, измените его на [^-\r\n].

Если \K не поддерживается, необходима группа захвата (а просмотр не поддерживается):

^(?:[^-]+-){2}([^-]+)-
2 голосов
/ 03 мая 2020

Вы можете сопоставить то, что находится между вторым и третьим дефисом, используя группу захвата, и сделать сопоставление остальных необязательным, используя повторяющийся шаблон с *

\w+(?:\s+-\s+\w+)\s+-\s+(\w+(?: \w+)*)(?:\s+-\s+\w+)*

Regex demo

2 голосов
/ 03 мая 2020

Используйте следующий шаблон с группой захвата, чтобы выделить то, что вы действительно хотите извлечь:

SAFE.REGEXP_EXTRACT(Final.CampaignName, r"[^-]+-[^-]+-\s*([^-]+?)\s*-") AS CampaignCategory

Демо

1 голос
/ 03 мая 2020

Я был почти там - так что ниже как можно ближе к вашей первоначальной идее (BigQuery Standard SQL)

SELECT IFNULL(REGEXP_EXTRACT(final.CampaignName, r"(?: - .*?){2}(.*?)(?: -|$)"), "Other") AS CampaignCategory
1 голос
/ 03 мая 2020

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

split(Final.CampaignName, ' - ')[safe_offset(2)]

Пример с вашими примерами данных:

select campaignName, split(campaignName, ' - ')[safe_offset(2)] as third_item
from unnest(['S - Oranges - Bar - Apples', 'S - Apples - Foo Bar - Oranges - Bananas', 'S - Apples - Bar']) as campaignName

Вывод выглядит так: enter image description here

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