Estoy realizando una investigación sobre identificar DOI en texto de formato libre.
Estoy usando Java 8 y REGEX
Encontré estos REGEX que se supone que cumplen mis requisitos
/^10.\d{4,9}/[-._;()/:A-Z0-9]+$/i /^10.1002/[^\s]+$/i /^10.\d{4}/\d+-\d+X?(\d+)\d+<[\d\w]+:[\d\w]*>\d+.\d+.\w+;\d$/i /^10.1021/\w\w\d++$/i /^10.1207/[\w\d]+\&\d+_\d+$/i
El código que estoy intentando es
private static final Pattern pattern_one = Pattern.compile("/^10.\\d{4,9}/[-._;()/:A-Z0-9]+$/i", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern_one.matcher("http://journals.ametsoc.org/doi/full/10.1175/JPO3002.1"); while (matcher.find()) { System.out.print("Start index: " + matcher.start()); System.out.print(" End index: " + matcher.end() + " "); System.out.println(matcher.group()); }
Sin embargo, el comparador no encuentra nada.
¿Dónde me he equivocado?
ACTUALIZAR
Encontré un DOI válido que mi conjunto de REGEX no coincide
aquí hay un ejemplo de DOI: 10.1175/1520-0485(2002)032<0870:CT>2.0.CO;2
¿Por qué no funciona este patrón?
/^10.\d{4}/\d+-\d+X?(\d+)\d+<[\d\w]+:[\d\w]*>\d+.\d+.\w+;\d$/i
Tu patrón me parece incorrecto. Actualmente estás usando esto:
/^10.\\d{4,9}/[-._;()/:A-Z0-9]+$/i
Pero creo que tienes la intención de usar esto:
^.*/10\\.\\d{4,9}/[-._;()/:A-Z0-9]+$
Los problemas con su patrón incluyen que está utilizando la sintaxis de expresiones regulares de JavaScript o la sintaxis de algún otro idioma. Además, no estaba escapando de un punto literal en la expresión regular, y el inicio del marcador de patrón estaba fuera de lugar.
Código:
String pattern = "^.*/10\\.\\d{4,9}/[-._;()/:A-Z0-9]+$"; String url = "http://journals.ametsoc.org/doi/full/10.1175/JPO3002.1"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(url); if (m.find( )) { System.out.println("Found value: " + m.group(0) ); } else { System.out.println("NO MATCH"); }
demostración aquí:
En Java, una expresión regular se escribe como una cadena. En otros idiomas, la expresión regular se cita usando /.../
, con opciones como i
dado después de la terminación /
. Entonces, lo que está escrito como /XXX/i
en Java se hará así:
// Using flags parameter Pattern p = Pattern.compile("XXX", Pattern.CASE_INSENSITIVE); // Using embedded flags Pattern p = Pattern.compile("(?i)XXX");
En la mayoría de los idiomas, las expresiones regulares se utilizan para encontrar una subcadena coincidente. Java también puede hacer eso, usando el método find()
(o cualquiera de los muchos métodos de replaceXxx()
), sin embargo, Java también tiene el método matches()
que coincidirá con toda la cadena, eliminando la necesidad de comenzar y terminar. emparejadores de límites ^
y $
.
De todos modos, su problema es que la expresión regular tiene emparejadores de límite ^
y $
, lo que significa que solo funcionará si la cadena no es más que el texto que desea hacer coincidir. Dado que realmente desea encontrar una subcadena, elimine esos emparejadores.
Para buscar uno de varios patrones, use el |
operador lógico de expresiones regulares.
Y finalmente, dado que la expresión regular de Java se proporciona como un literal de cadena, cualquier carácter especial, en particular \
, debe escaparse.
Entonces, para construir una sola expresión regular que pueda encontrar subcadenas que coincidan con cualquiera de los siguientes:
/^10.\d{4,9}/[-._;()/:A-Z0-9]+$/i /^10.1002/[^\s]+$/i /^10.\d{4}/\d+-\d+X?(\d+)\d+<[\d\w]+:[\d\w]*>\d+.\d+.\w+;\d$/i /^10.1021/\w\w\d++$/i /^10.1207/[\w\d]+\&\d+_\d+$/i
Lo escribirías así:
String regex = "10.\\d{4,9}/[-._;()/:A-Z0-9]+" + "|10.1002/[^\\s]+" + "|10.\\d{4}/\\d+-\\d+X?(\\d+)\\d+<[\\d\\w]+:[\\d\\w]*>\\d+.\\d+.\\w+;\\d" + "|10.1021/\\w\\w\\d++" + "|10.1207/[\\w\\d]+\\&\\d+_\\d+"; Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); String input = "http://journals.ametsoc.org/doi/full/10.1175/JPO3002.1"; Matcher m = p.matcher(input); while (m.find()) { System.out.println("Start index: " + m.start() + " End index: " + m.end() + " " + m.group()); }
Producción
Start index: 37 End index: 54 10.1175/JPO3002.1