Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
906
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Поиск DOI в документе или странице
Система DOI в принципе не накладывает никаких полезных ограничений на то, что представляет собой разумный идентификатор . Однако, будучи в состоянии вытащить DOIs из PDFs, веб-страниц и т. д. весьма полезна для цитирования информация и т.д.
Существует ли надежный способ определить DOI в блоке текста, не предполагая префикс ' doi:'? (любой приемлемый язык, предпочтительные регексы и предотвращение ложных срабатываний обязательно)
Хорошо, в настоящее время я извлекаю тысячи DOIs из текста свободной формы (XML), и я понял, что мой предыдущий подход имел несколько проблем, а именно в отношении кодированных сущностей и пунктуации trail, поэтому я продолжал читать спецификацию , и это лучшее, что я мог предложить.
Префикс DOI должен состоять из Указателя каталога, за которым следует код владельца регистрации. Эти два компонента должны быть разделены полным стоп (точка).
Показатель каталога должен быть равен "10". Индикатор каталога различает весь набор символьных строк (префикс и суффикс) как цифровые идентификаторы объектов в системе разрешения.
Достаточно просто, начальный \b предотвращает нас от "matching" a "DOI", который не начинается с 10. :
$pattern = '\b(10[.]';
Вторым элементом префикса DOI должен быть код владельца регистрации. То код владельца регистрации - это уникальная строка, назначенная владельцу регистрации.
Кроме того, все присвоенные регистранту коды являются цифровыми и имеют длину не менее 4 цифр, поэтому:
$pattern = '\b(10[.][0-9]{4,}';
Код владельца регистрации может быть дополнительно разделен на подэлементы для административное удобство при желании. Каждый подэлемент системы код владельца регистрации должен предшествовать полной остановке.
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*';
Синтаксис DOI должен состоять из префикса DOI и суффикса DOI разделенные прямой косой чертой.
Однако это не является абсолютно необходимым, раздел 2.2.3 утверждает, что необычные суффиксальные системы могут использовать другие соглашения (например, 10.1000.123456 вместо 10.1000/123456), но позволяет сократить некоторые пробелы.
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/';
Имя DOI не чувствительно к регистру и может включать любую печатную версию символы из юридических графических символов Юникода. В DOI суффикс должен состоять из символьной строки любой длины, выбранной пользователем. регистрант. Каждый суффикс должен быть уникальным для префиксного элемента, который предшествовать ему. Уникальным суффиксом может быть порядковый номер, а может и наоборот включить идентификатор, созданный из другой системы или основанный на ней.
Теперь это становится сложнее, из всех DOIs, которые я обработал, я увидел следующие символы (кроме [0-9a-zA-Z] , конечно) в их суффиксах : .-()/:- -так что, хотя он и не существует, DOI 10.1016.12.31/nature.S0735-1097(98)2000/12/31/34:7-7 вполне правдоподобен.
Логическим выбором было бы использовать класс \S или [[:graph:]] PCRE POSIX, поэтому давайте сделаем это:
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/\S+'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/[[:graph:]]+';
Теперь у нас есть сложная проблема, класс [[:graph:]] -это супер-набор класса [[:punct:]] , который включает символы, легко найденные в свободном тексте или любом языке markup: "'&<> среди других.
Давайте просто фильтровать markup сейчас, используя отрицательный просмотр вперед:
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+';
Вышесказанное должно охватывать закодированные сущности ( & ), кавычки атрибутов ( ["'] ) и теги открытия / закрытия ([<>] ).
В отличие от markup языков, в свободном тексте обычно не используются знаки препинания, если они не ограничены хотя бы одним пробелом или не помещены в конце предложения, например:
Это очень долго DOI:
10.1016.12.31/nature.S0735-1097(98)2000/12/31/34:7-7!!!
Решение здесь состоит в том, чтобы закрыть нашу группу захвата и утвердить другую границу слова:
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+)\b'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+)\b';
И вуаля, вот вам демо-версия .
@Silas проверка вменяемости-хорошая идея. Однако regex не покрывает все DOIs. Первый элемент должен (в настоящее время) быть be 10, а второй элемент должен (в настоящее время) быть числовым, но третий элемент практически не ограничен:
"Юридические символы - это юридические графические символы Юникода. Это специально исключает диапазоны управляющих символов 0x00-0x1F и 0x80-0x9F..."
и вот тут-то и кроется настоящая проблема. На практике я никогда не видел, чтобы whitespace использовался, но спецификация специально допускает это. В принципе, похоже, что нет разумного способа обнаружить конец DOI.
CrossRef имеет рекомендацию, что они успешно протестированы на 99.3% из DOIs:
/^10.\d{4,9}/[-._;()/:A-Z0-9]+$/i
Я уверен, что это не очень полезно для OP в данный момент, но я решил опубликовать то, что я пытаюсь, если кто-то еще, как я, наткнется на это:
(10.(\d)+/(\S)+)
Это соответствует: "10 точечный номер Слэш anything-not-whitespace"
Но для моего использования (выскабливание HTML) это было обнаружение ложных срабатываний, поэтому мне пришлось сопоставить вышеописанное, а также избавиться от кавычек и greater-than/less-than:
(10.(\d)+/([^(\s\>\"\<)])+)
Я все еще проверяю их, но до сих пор чувствую надежду.
Вот мой ход на это:
(10[.][0-9]{4,}[^\s"/<>]*/[^\s"<>]+)
И несколько допустимых крайних случаев, когда это не терпит неудачи, но другие, похоже, делают это:
-
10.1007/978-3-642-28108-2_19 10.1007.10/978-3-642-28108-2_19(фиктивный пример, см. комментарий @Ju9OR )-
10.1016/S0735-1097(98)00347-7 -
10.1579/0044-7447(2006)35\[89:RDUICP\]2.0.CO;2
Кроме того, правильно отбрасывает некоторые ложные (X|HT)ML вещи, такие как:
<geo coords="10.4515260,51.1656910"></geo>
Следующий regex должен выполнить эту работу (синтаксис Perl regex):
/(10\.\d+\/\d+)/
Вы можете сделать некоторые дополнительные проверки вменяемости, открыв URL-адреса
http://hdl.handle.net/<doi>
и
http://dx.doi.org/<doi>
где находится кандидат doi,
и проверка того, что вы а) получаете статус 200 OK http, и Б) возвращенная страница не является страницей "DOI not found" для службы.