gpt4 book ai didi

regex - 在文档或页面中查找 DOI

转载 作者:行者123 更新时间:2023-12-03 06:35:38 25 4
gpt4 key购买 nike

DOI系统对 a reasonable identifier 的构成基本上没有任何有用的限制。 。然而,能够从 PDF、网页等中提取 DOI 对于引文信息等非常有用。

是否有一种可靠的方法可以在不使用“doi:”前缀的情况下识别文本 block 中的 DOI? (任何可接受的语言,首选正则表达式,并且必须避免误报)

最佳答案

好的,我目前正在从自由格式文本 (XML) 中提取数千个 DOI,我意识到 my previous approach 有一些问题,即关于编码实体和尾随标点符号,所以我继续阅读 the specification,这是我最好的可以附带。

<小时/>

The DOI prefix shall be composed of a directory indicator followed bya registrant code. These two components shall be separated by a fullstop (period).

The directory indicator shall be "10". The directory indicatordistinguishes the entire set of character strings (prefix and suffix)as digital object identifiers within the resolution system.

很简单,初始的 \b 会阻止我们“匹配”不以 10. 开头的“DOI”:

$pattern = '\b(10[.]';
<小时/>

The second element of the DOI prefix shall be the registrant code. Theregistrant code is a unique string assigned to a registrant.

此外,所有分配的注册人代码都是数字,且长度至少为 4 位,因此:

$pattern = '\b(10[.][0-9]{4,}';
<小时/>

The registrant code may be further divided into sub-elements foradministrative convenience if desired. Each sub-element of theregistrant code shall be preceded by a full stop.

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*';

<小时/>

The DOI syntax shall be made up of a DOI prefix and a DOI suffixseparated by a forward slash.

但是,这并不是绝对必要的,第 2.2.3 节指出,不常见的后缀系统可能会使用其他约定(例如 10.1000.123456 而不是 10.1000/123456 ),但让我们放松一下。

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/';

<小时/>

The DOI name is case-insensitive and can incorporate any printablecharacters from the legal graphic characters of Unicode. The DOIsuffix shall consist of a character string of any length chosen by theregistrant. Each suffix shall be unique to the prefix element thatprecedes it. The unique suffix can be a sequential number, or it mightincorporate an identifier generated from or based on another system.

现在事情变得更棘手了,从我处理过的所有 DOI 中,我在其后缀中看到了以下字符(当然除了 [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:]] 类的超集,其中包括在自由文本或任何标记语言中轻松找到的字符:"'&<> 等。

现在让我们使用否定前瞻来过滤标记:

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+'; // or

$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+';

<小时/>

以上内容应涵盖编码实体 (&)、属性引号 (["']) 和打开/关闭标记 ([<>])。

与标记语言不同,自由文本通常不使用标点符号,除非它们至少有一个空格放置在句子的末尾,例如:

This is a long 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';

还有here is a demo

关于regex - 在文档或页面中查找 DOI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27910/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com