SQL Server извлекает целые числа из строки с помощью регулярного выражения - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть строка (путь к unc-файлу), которая мне нужна для извлечения некоторых целых чисел, которые будут встраиваться в строку полу-предсказуемым образом.

Примеры строк:

\\servername\folder1\FTP\folder2\512/862450_FileBundle.zip
--OR-- : \\servername\folder1\FTP\folder2\512\862450_FileBundle.zip
--OR-- : servername/folder1/FTP/folder2/512/862450_FileBundle.zip

Следующее регулярное выражение регулярного выражения будет соответствовать любому целочисленному значению, ограниченному прямой или обратной косой чертой: (\/|\\)\d+(\/|\\)

Таким образом, приведенный выше REGEX будет соответствовать "\ 512 \" или "\ 512 /"или "/ 512 /" или даже "/512\".

Я безуспешно пробовал следующие SQL и другие варианты:

DECLARE @testString varchar(50) = '\\servername\folder1\FTP\folder2\512/862450_FileBundle.zip'
SELECT PATINDEX('%(\/|\\)\d+(\/|\\)%', @testString)

Я не очень знаком с REGEXи SQL, так что я даже не уверен, что это возможно.

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

SQL Server не обладает такими хорошими возможностями сопоставления с образцом, как регулярные выражения.Вы можете искать шаблон:

[/\\][0-9]%[/\\]

То есть косая черта, за которой следует цифра, за которой следует любая другая строка, за которой следует косая черта.Это будет соответствовать любым символам после первой цифры, но ваши примеры не имеют ничего вида /1abc/.

Если этого достаточно, то это делает трюк:

select v.*, 
       left(v2.str2, patindex('%[/\\]%', v2.str2) - 1)
from (values ('\\servername\folder1\FTP\folder2\512/862450_FileBundle.zip')) v(str) cross apply
     (values (stuff(v.str, 1, patindex('%[/\\][0-9]%[/\\]%', v.str), ''))) v2(str2)
0 голосов
/ 04 декабря 2018

Кроме написания UDF для циклического прохождения символов, единственное, о чем я могу думать, это метод грубой силы ...

(Определяемая пользователем функция может быть вашим наихудшим вариантом).

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=face1befe5e7c74f457846fc37eca649

SELECT
  *,
  SUBSTRING(test.unc_file_path, headMatch.pos+1, headMatch.chars)
FROM
  test
OUTER APPLY
(
  SELECT
    MIN(pos), MIN(chars)
  FROM
  (
    SELECT
      PATINDEX('%' + head + body + tail + '%', test.unc_file_path)  AS pos, chars
    FROM
    (
                 SELECT '\'
       UNION ALL SELECT '/'
    )
      head(head)
    CROSS JOIN
    (
                 SELECT 1, '[0-9]'
       UNION ALL SELECT 2, '[0-9][0-9]'
       UNION ALL SELECT 3, '[0-9][0-9][0-9]'
       UNION ALL SELECT 4, '[0-9][0-9][0-9][0-9]'
       UNION ALL SELECT 5, '[0-9][0-9][0-9][0-9][0-9]'
    )
      body(chars, body)
    CROSS JOIN
    (
                 SELECT '\'
       UNION ALL SELECT '/'
    )
      tail(tail)
  )
    match
  WHERE
    pos > 0
)
  headMatch(pos, chars)
...