Как проверить, является ли строка действительной ссылкой Figma?
Я создаю приложение на NodeJS, которое использует Figma API, и мне нужно проверить, является ли строка, переданная пользователем, действительной ссылкой Figma. В настоящее время я использую это простое выражение регулярного выражения, чтобы проверить строку:
/^https\:\/\/www.figma.com\/.*/i
Тем не менее, он соответствует всем ссылкам из figma.com
Даже домашняя страница, не только ссылки на файлы и прототипы. Вот пример ссылки Figma, которая должна соответствовать:
https://www.figma.com/file/OoYmkiTlusAzIjYwAgSbv8wy/Test-File?node-id=0%3A1
Также совпадение должно быть положительным, если это ссылка на прототип, с proto
вместо file
в пути.
Более того, поскольку я использую API Figma, было бы полезно извлечь необходимые части URL, такие как идентификатор файла и идентификатор узла одновременно.
1 ответ
TL; DR
✅ Используйте это выражение, чтобы захватить четыре наиболее важные группы (тип, идентификатор файла, имя файла и свойства URL) и работать оттуда.
/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/?([^\?]+)?(.*))?$/
Из документов
Это код выражения регулярного выражения, предоставленный Figma на странице документации для разработчиков по встраиванию:
/https://([w.-]+.)?figma.com/(file|proto)/([0-9a-zA-Z]{22,128})(?:/.*)?$/
Однако, это не работает в JS, поскольку документация в настоящее время неверна, и у этого выражения есть много проблем:
Косые черты и точки не спасаются от обратных косых черт.
Это не совпадает с начала строки. Я добавил начало привязки строки
^
после того, как ВЛАЗ указал на это в комментариях. Таким образом, мы избежим совпадения строк, которые не начинаются сhttps
, напримерmalicious.site/?link=https://figma.com/...
Это будет соответствовать не только
www.
субдомен, но любое другое количество W, которое не велико (например,wwwww.
) - это можно исправить, заменив совпадение букв более простым выражением. Также это бесполезная группа захвата, я сделаю это без захвата.Было бы хорошо, если бы ссылка соответствовала, даже если она не начинается с
https://
поскольку некоторые движки (например, Twitter) сокращают эту часть для краткости, и если человек копирует ссылку оттуда, она все равно должна быть действительной.
После применения всех улучшений у нас остается следующее выражение:
/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?$/
Существует также специальный пакет NPM, который просто проверяет URL по аналогичному шаблону. Тем не менее, он содержит некоторые недостатки, перечисленные выше, поэтому я не советую использовать его, особенно для одной строки кода.
Извлечение частей URL
Это выражение чрезвычайно полезно для использования с Figma API, поскольку оно даже извлекает из URL необходимые части, такие как тип ссылки (proto/file) и ключ файла. Вы можете получить к ним доступ по индексам.
Вы также можете добавить часть регулярного выражения для соответствия определенным ключам в запросе, например: node-id
:
/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?node-id=([^&]*)$/
Теперь вы можете использовать его в коде и получать все части URL отдельно:
var pattern = /^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?node-id=([^&]*)$/
var matched = 'https://www.figma.com/file/OoYmkiTlusAzIjYwAgSbv8wy/Test-File?node-id=0%3A1'.match(pattern)
console.log('url:', matched[0]) // whole matched string
console.log('type:', matched[1]) // group 1
console.log('file key:', matched[2]) // group 2
console.log('node id:', matched[3]) // group 3
Копать глубже
Я потратил некоторое время на то, чтобы воссоздать это выражение практически с нуля, чтобы оно соответствовало как можно большему количеству возможных URL-адресов файлов / прототипов Figma без каких-либо проблем. Вот три аналогичные версии, которые будут работать для разных случаев.
✅ Эта версия захватывает параметры URL и имя файла отдельно для облегчения обработки. Вы можете проверить это здесь. Я добавил его в начале ответа, потому что считаю, что это самое чистое и полезное решение.
/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/?([^\?]+)?(.*))?$/
Группы в нем следующие:
- Группа 1: файл / протокол
- Группа 2: ключ файла / идентификатор
- Группа 3: имя файла (необязательно)
- Группа 4: параметры URL (необязательно)
✅ Далее я хотел сделать то же самое, но отделяя /duplicate
часть, которая может быть добавлена в конце любого URL-адреса Figma для создания дубликата файла при открытии.
/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/?([^\?]+)?([^\/]*)(\/duplicate)?)?$/
Back И вернемся к node-id
параметр. Следующее выражение регулярного выражения успешно находит и захватывает несколько URL-адресов внутри многострочной строки. Единственный недостаток, который я обнаружил в конце, заключается в том, что он (как и все предыдущие) не проверяет, содержит ли этот URL незашифрованные специальные символы, что означает, что он потенциально может что-то сломать, но этого можно избежать, вручную кодируя все параметры с помощью encodeURI()
функция
/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/([^\?\n\r\/]+)?((?:\?[^\/]*?node-id=([^&\n\r\/]+))?[^\/]*?)(\/duplicate)?)?$/gm
Есть шесть групп, которые могут быть захвачены этим выражением:
- Группа 1: файл / протокол
- Группа 2: ключ файла / идентификатор
- Группа 3: имя файла (необязательно)
- Группа 4: параметры URL (необязательно)
- Группа 5: идентификатор узла (необязательно; присутствует только при наличии группы 4)
- Группа 6: / Дублировать
И, наконец, вот пример матча и его групп (или попробуйте сами):