¿Cómo puedo extraer una expresión numérica de un string
, que puede tener o no underscore
o hyphen
? Por ej. como 2016-03
o 2016_03
o simplemente 201603
.
Cadenas de muestra:
s = 'Total revenue for 2016-03 is 3000 €' # Output 2016-03
s = 'Total revenue for 2016_03 is 3000 €' # Output 2016_03
s = 'Total revenue for 201603 is 3000 €' # Output 201603
Hay 6 números y en caso de que tengamos -
o _
, entonces la longitud total es 7. No hay otros number
en toda la cadena.
No sé cómo usar if-else
en regex
, por lo que puede incluir la lógica de longitud 6 o 7. Para cadenas simples como 201603
, puedo hacerlo:
import re
print(re.findall('\d{6}','Total revenue for 201603 is 3000 €'))
['201603']
print(re.findall('\d{6}','Total revenue for 2016-03 is 3000 €'))
[]
Nota: estoy buscando una solución en la que teóricamente _
o -
podrían estar entre el número de 6 longitudes. Como 123-456
o 123456
o 12345-6
y así sucesivamente.
4 respuestas
Puede haber dos enfoques: uno es más legible al dividir la cadena primero y luego obtener el primer elemento que coincida con su patrón requerido, o un enfoque menos legible con una sola expresión regular.
Consulte la demostración de Python:
import re
s = 'Total revenue for 201603 is 3000 €'
rx = re.compile(r'^(?=\d+(?:[_-]\d+)?$)[\d_-]{6,7}$')
res = [x for x in s.split() if rx.search(x)]
if len(res):
print(res[0])
# Pure regex approach:
rx = re.compile(r'(?<!\S)(?=\d+(?:[_-]\d+)?(?!\S))[\d_-]{6,7}(?!\S)')
res = rx.search(s)
if res:
print(res.group())
Entonces, en el primer enfoque, la cadena se divide con espacios en blanco, y se aplica un patrón ^(?=\d+(?:[_-]\d+)?$)[\d_-]{6,7}$
a cada elemento, y si hay coincidencias, se devuelve el primero. El patrón coincide:
^
- inicio de cadena(?=\d+(?:[_-]\d+)?$)
: una anticipación positiva que asegura que haya 1+ dígitos, luego_
o-
, y luego de nuevo 1+ dígitos hasta el final de la cadena,[\d_-]{6,7}
: coincide con 6 o 7 dígitos,-
o_
$
- fin de la cadena.
El segundo enfoque involucra solo expresiones regulares y el anclaje ^
se responde con (?<!\S)
y $
se reemplaza con (?!\S)
que actúan como límites de espacios en blanco. (?<!\S)
es una mirada hacia atrás negativa que requiere un espacio en blanco o el inicio de la cadena justo antes de la posición actual y (?!\S)
es una búsqueda negativa hacia adelante que requiere un espacio en blanco o el final de la cadena justo después de la posición actual.
Esto debería hacerlo de manera bastante simple:
print(re.findall(r'\d{4}[-_]?\d{2}', 'Total revenue for 201603 is 3000 €'))
# ['201603']
Específicamente, esto es "Cuatro dígitos, seguidos de cero o una aparición de '-'
o '_'
, seguido de dos dígitos más". Si no hay un guión o guión bajo, los cuatro dígitos y los dos dígitos terminan igual que pedir seis dígitos.
Sin embargo, este captura el guión o el guión bajo si está allí, por lo que una cosa que puede hacer es filtrarlo:
nums = re.findall(r'\d{4}[-_]?\d{2}', 'Total revenue for 2016-03 is 3000 €')
# nums = ['2016-03']
nums = [num.replace('-', '').replace('_', '') for num in nums]
# nums = ['201603']
Tenga en cuenta que esta es la solución que menos perturba su expresión regular original, y buscará este patrón de "cuatro dígitos seguido de quizás un separador y luego dos dígitos" en cualquier parte de la cadena. Si desea restringir esto a solo la cadena que está tratando de buscar, ignorando las similares, es posible que deba hacer que la expresión regular sea más específica. Consulte también la documentación re
Su RegEx es el siguiente: comienza con espacio, secuencia de al menos un dígito (s) y termina con espacio. Se trata de esto:
\s(\d*)\s
Compruébalo aquí: https://regex101.com/r/V4NzLj/1
Puede usar una mirada hacia atrás positiva si está seguro de que su valor requerido siempre sigue un patrón estándar
(?<=^Total revenue for )\d+[-_]?\d+
(?<=^Total revenue for )
- La coincidencia debe estar precedida porTotal revenue for
,^
comenzar desde el inicio de la cadena\d+
: coincide con uno o más dígitos[-_]?
- Match- or _
(opcional)
O puede extender la expresión regular anterior de tal manera si no está seguro de que el formato de valor requerido
(?<=^Total revenue for )(?=\d+[-_]?\d+)[\d_-]{6,7}(?!\S)
(?=\d+[-_]?\d+)
- Para garantizardigit followed by - or _ optional followed by digit
[\d_-]{6,7}
- Para que coincida condigit or - or _, 6 or 7 times
(?!\S)
: no debe ir seguido de un carácter que no sea espacio
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.