Ok, actualmente estoy extrayendo miles de DOI de texto de forma libre (XML) y me di cuenta de que my previous approach tenía algunos problemas, a saber, con respecto a las entidades codificadas y la puntuación final, así que seguí leyendo the specification y esto es lo mejor que pude encontrar.
El prefijo DOI estarán compuestos de un indicador de directorio seguido por un código de registro. Estos dos componentes deben estar separados por una parada completa (punto).
El indicador de directorio debe ser "10". El indicador de directorio distingue el conjunto completo de cadenas de caracteres (prefijo y sufijo) como identificadores de objetos digitales dentro del sistema de resolución.
bastante fácil, la inicial \b
nos impide "juego" a "DOI" que no se inicia con 10.
:
$pattern = '\b(10[.]';
El segundo elemento del prefijo DOI deben ser el código de registro. El código de registrador es una cadena única asignada a un registrante.
También, todo el código de registro asignado son numéricas, y al menos 4 dígitos de longitud, así que:
$pattern = '\b(10[.][0-9]{4,}';
El código de registro se puede dividir en sub-elementos para administrativa conveniencia si lo desea Cada subelemento del código de registrador irá precedido por un punto.
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*';
La sintaxis DOI se compone de un prefijo y un sufijo DOI DOI separados por una barra inclinada.
Sin embargo, esto no es absolutamente necesario, la sección 2.2.3 establece que los sistemas de sufijos comunes pueden utilizar otras convenciones (como 10.1000.123456
en lugar de 10.1000/123456
), pero deja cortar un poco de holgura.
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/';
El nombre DOI es sensible a las mayúsculas y puede incorporar cualquier caracteres imprimibles de los caracteres gráficos legales de Unicode. El sufijo DOI consistirá en una cadena de caracteres de cualquier longitud elegida por el registrante . Cada sufijo debe ser exclusivo del elemento de prefijo que lo precede . El sufijo único puede ser un número secuencial, o podría incorporar un identificador generado a partir de o basado en otro sistema.
Ahora bien, esto es donde se pone más complicado, de todo el DOI he procesado, vi los siguientes caracteres (además [0-9a-zA-Z]
por supuesto) en sus sufijos: .-()/:-
- por lo que, si bien no existe , el DOI 10.1016.12.31/nature.S0735-1097(98)2000/12/31/34:7-7
es completamente plausible.
La elección lógica sería utilizar \S
o la clase [[:graph:]]
PCRE POSIX, por lo que permite hacer eso:
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/\S+'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/[[:graph:]]+';
Ahora tenemos un problema difícil, la clase [[:graph:]]
es un super-conjunto de la clase [[:punct:]]
, que incluye caracteres que se encuentran fácilmente en texto libre o en cualquier lenguaje de marcado: "'&<>
entre otros.
Permite sólo filtrar las marcado por ahora usando una búsqueda negativa hacia delante:
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+';
las entidades anteriores deben cubrir codificados (&
), atribuir las citas (["']
) y las etiquetas de apertura/cierre ([<>]
) .
A diferencia de los lenguajes de marcas, texto libre por lo general no emplea caracteres de puntuación a menos que sean delimitado por al menos un espacio o colocado al final de una frase, por ejemplo:
Este es un largo DOI: 10.1016.12.31/nature.S0735-1097(98)2000/12/31/34:7-7
!!!
Aquí la solución es cerrar nuestro grupo de captura y hacer valer otro límite de palabra:
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+)\b'; // or
$pattern = '\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+)\b';
Y voilá , here is a demo.
No es el caso (o ya no es el caso) que todos los códigos de registrante asignados tengan al menos cuatro dígitos de longitud. Por ejemplo, 10.231 es el Journal of Investigative Medicine. Por ejemplo, 10.231/JIM.0b013e31820bab4c –
@DavidConrad: ¡Gracias por la actualización hombre! –
Wiley usa "<" and ">" en sus DOI. Por ejemplo, 10.1002/(SICI) 1522-2594 (199911) 42: 5 <952 :: AID-MRM16> 3.0.CO; 2-S es un DOI válido. Este DOI no es capturado por la expresión regular anterior. Una solución rápida es eliminar las etiquetas de abrir/cerrar del conjunto de caracteres que no son DOI. (Consulte https://sourceforge.net/p/jabref/patches/203/) – koppor