Extract name between a word and comma from text with regex - python

I have a thousands .txt files with a large text. I want to extract some information from these files, like some names, numbers and dates. There are fields that follow a pattern to be able to extract the information, but others do not. I attach three examples of text.
The problem comes when I need to extract the name of the creator of a company and the name of that company. To extract the name of the creator, there is a pattern in the text. To extract the name of the company no.
The pattern is: start with the words "ante mí:" followed by a name with last names and ending in comma.
I am using the following code:
# Libreria RegEx de Python.
# coding=utf-8
import re
f = open ('/Users/anna/PycharmProjects/extractData/DiarioOficial/aaa1381582.pdf.txt','r')
mensaje = f.read()
mensaje = mensaje.replace("\n","")
print re.findall(r'\s ante mí,+[a-zA-Z]{6-24}\s', mensaje)
But I think that the regular expression is wrong.
Can someone help me?
CVE 1381582
|
Director: Juan Jorge Lazo Rodríguez
Sitio Web:
www.diarioficial.cl
|
Mesa Central:
+562 2486 3600
    Email:
consultas#diarioficial.cl
Dirección:
Dr. Torres Boonen N°511, Providencia, Santiago, Chile.
Este documento ha sido firmado electrónicamente de acuerdo con la ley N°19.799 e incluye sellado de tiempo y firma electrónica
avanzada. Para verificar la autenticidad de una representación impresa del mismo, ingrese este código en el sitio web www.diarioficial.cl
DIARIO OFICIAL
DE LA REPUBLICA DE CHILE
Ministerio del Interior y Seguridad Pública
V
SECCIÓN
CONSTITUCIONES, MODIFICACIONES Y DISOLUCIONES DE SOCIEDADES Y COOPERATIVAS
Núm. 42.031
|
Viernes 13 de Abril de 2018
|
Página 1 de 1
Empresas y Cooperativas
CVE 1381582
EXTRACTO
 
VALERIA RONCHERA FLORES, Notario Titular Décima Notaría Santiago, oficio
Agustinas 1235, piso 2, CERTIFICO: Por escritura pública hoy ante mí: DANIEL ROLANDO
CORNEJO GALLARDO, chileno, soltero, factor de comercio, con domicilio en Pueblo Hundido
sin número, comuna de Rengo, Sexta Región del Libertador Bernardo OHiggins, de paso en
ésta; constituyó sociedad por acciones denominada AGRÍCOLA Y TRANSPORTES SAN
DANIEL SpA, nombre de fantasía SAN DANIEL SpA. Objeto Social: Objeto. La Sociedad
tiene por objeto, la explotación integral del rubro agrícola, ganadero y forestal, por cuenta propia
o ajena, de predios rústicos propios o ajenos, la importación, exportación, transformación y
comercialización de productos agrícolas, ganaderos o forestales. En general, la realización de
toda clase de negocios relacionados con el agro, la producción agropecuaria, frutícola o
maderera, la compra, venta y exportación de la producción, sea la propia o ajena, servicios de
embalaje, envasado, packing y de asesoría a productores, y la elaboración de alimentos, de toda
clase a partir de esa producción; actuar como comisionista o mandatario, para la venta y
comercio de productos agrarios; realizar inversiones en toda clase de bienes muebles o
inmuebles, administrarlos y percibir sus frutos o rentas. Asimismo, el transporte de carga y/o
pasajeros, en vehículos propios, arrendados o en leasing o encomendados a terceros; la
representación de empresas extranjeras o nacionales de transporte y embalaje; todo lo
relacionado, de cualquiera forma, en la actualidad o en el futuro, con el flete, traslado y
transporte de pasajeros o bienes de toda clase y su embalaje, incluyendo las gestiones portuarias
y aduaneras, en su caso. También el ejercicio de la actividad comercial en sus formas más
amplias y, en especial, la compraventa, importación, exportación, distribución y
comercialización de toda clase de bienes, por cuenta propia o ajena, la representación de
empresas nacionales y extranjeras; y todo otro negocio o actividad conexa con el giro que
acuerden los socios. Domicilio: Comuna y ciudad de Santiago, Región Metropolitana, sin
perjuicio de que pueda establecer agencias, sucursales u oficinas en el resto del país o en el
extranjero. Duración: Indefinida. Capital: $100.000.000.- dividido en 1.000 acciones,
nominativas, de una sola serie y sin valor nominal; de las cuales el socio constituyente paga 10
acciones, equivalentes a $1.000.000.-, al contado, en efectivo, que ingresan a caja social, el saldo
de 990 acciones serán pagadas en un plazo de 3 años a contar de la suscripción del presente
contrato. Administración: Por accionista constituyente DANIEL ROLANDO CORNEJO
GALLARDO.- Demás pactos escritura extractada. "Santiago, 9 abril 2018".

Use the pattern ([^,]*) to match everything upto a comma
>>> re.findall(r'\sante mí:\s+([^,]*)', mensaje)
['DANIEL ROLANDO CORNEJO GALLARDO']

Related

Separate list obtained with selenium Python

I am developing a script to scrape a page of hotels.com with selenium
import time
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import pandas as pd
import csv
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get('https://es.hoteles.com/ho227810/secrets-lanzarote-resort-spa-adults-only-18-yaiza-espana/')
time.sleep(3)
try:
cookies = driver.find_element(By.CLASS_NAME, 'osano-cm-button--type_accept')
cookies.click()
time.sleep(2)
except:
pass
try:
tamano_hotel = driver.find_elements(By.XPATH, '//*[#id="Amenities"]/div/div[1]/div/div[2]')
hotel=[]
for iterarhotel in tamano_hotel:
hotel.append(iterarhotel.text)
print(hotel)
time.sleep(2)
except:
print("Nothing")
It extracts it as a list
['Tamaño del hotel\n331 habitaciones\nCuenta con 8 pisos\nEntrada y salida\nHorario del registro de entrada: de 15:00 a 0:00\nEdad mínima para efectuar el registro de entrada: 18\nSe puede efectuar el registro de salida hasta las 12:00\nRestricciones relacionadas con tu viaje\nConsulta las restricciones por el COVID-19.\nInstrucciones especiales de entrada\nEl personal de recepción estará esperando a los huéspedes a su llegada.\nPara obtener más información, ponte en contacto con el alojamiento a través de los datos que aparecen en la confirmación de la reserva.\nLos restaurantes del establecimiento abren en función de la temporada.\nDocumentación para el registro de entrada\nEs obligatorio presentar una tarjeta de crédito o de débito, o dejar un depósito en efectivo, para posibles cargos adicionales.\nPueden pedirte un documento de identidad válido.\nLa edad mínima para alojarse en este alojamiento es de 18 años\nLa edad mínima para realizar el registro de entrada es de 18 años.\nMenores\nCunas no disponibles\nMascotas\nSe admiten mascotas (solo perros y gatos, 1 por habitación hasta 10 kg)*\nCon restricciones*\nInternet\nConexión wifi gratis en las zonas comunes\nConexión wifi gratis en las habitaciones\nAparcamiento\nAparcamiento sin asistencia gratuito en las instalaciones\nAparcamiento para coches accesible en silla de ruedas en las instalaciones\nTraslados\nTraslado desde/hasta el aeropuerto*\nInformación adicional\nAlojamiento para no fumadores\nSolo para adultos']
I am trying to scrape the Amenities part but I get the list all together, how could I separate it in a way that it would be separated like this?
Tamaño del hotel: 331 habitaciones, Cuenta con 8 pisos
Entrada y salida: Horario del registro de entrada: de 15:00 a 0:00, Edad mínima para efectuar el registro de entrada: 18, Se puede efectuar el registro de salida hasta las 12:00
Restricciones relacionadas con tu viaje: Consulta las restricciones por el COVID-19.
etc...
Create an empty dictionary object and add the key as header and value and li elements.
I have changed the locator as well.
try:
tamano_hotel = driver.find_elements(By.CSS_SELECTOR, 'section#Amenities div.uitk-layout-columns-item')
hotel=[]
dictdetails={}
for iterarhotel in tamano_hotel:
dictdetails[iterarhotel.find_element(By.XPATH, ".//h3").text]=",".join([item.text for item in iterarhotel.find_elements(By.XPATH, ".//ul//li")])
hotel.append(dictdetails)
print(hotel)
time.sleep(2)
except:
print("Nothing")
Console output:
[{'Tamaño del hotel': '331 habitaciones,Cuenta con 8 pisos', 'Entrada y salida': 'Horario del registro de entrada: de 15:00 a 0:00,Edad mínima para efectuar el registro de entrada: 18,Se puede efectuar el registro de salida hasta las 12:00', 'Restricciones relacionadas con tu viaje': 'Consulta las restricciones por el COVID-19.', 'Instrucciones especiales de entrada': 'El personal de recepción estará esperando a los huéspedes a su llegada.,Para obtener más información, ponte en contacto con el alojamiento a través de los datos que aparecen en la confirmación de la reserva.,Los restaurantes del establecimiento abren en función de la temporada.', 'Documentación para el registro de entrada': 'Es obligatorio presentar una tarjeta de crédito o de débito, o dejar un depósito en efectivo, para posibles cargos adicionales.,Pueden pedirte un documento de identidad válido.,La edad mínima para alojarse en este alojamiento es de 18 años,La edad mínima para realizar el registro de entrada es de 18 años.', 'Menores': 'Cunas no disponibles', 'Mascotas': 'Se admiten mascotas (solo perros y gatos, 1 por habitación hasta 10 kg)*,Con restricciones*', 'Internet': 'Conexión wifi gratis en las zonas comunes,Conexión wifi gratis en las habitaciones', 'Aparcamiento': 'Aparcamiento sin asistencia gratuito en las instalaciones,Aparcamiento para coches accesible en silla de ruedas en las instalaciones', 'Traslados': 'Traslado desde/hasta el aeropuerto*', 'Información adicional': 'Servicio de limpieza diario,Caja fuerte', 'Comida y bebida': '6 restaurantes,5 bares o lounges,Bar junto a la piscina,Cafetería,Café y té en una zona común,Servicio de habitaciones las 24 horas,Snack-bar o delicatessen', 'Actividades': 'Tenis,Ráquetbol o squash,Vóleibol,Submarinismo,Cerca de la playa,Rutas a pie o en bicicleta en las inmediaciones,Ciclismo de montaña en las inmediaciones,Kayak en las inmediaciones,Esnórquel en las inmediaciones,Alquiler de ciclomotores o scooters en las inmediaciones', 'Teletrabajo': 'Centro de negocios abierto las 24 horas,5 salas de reuniones,Sala de ordenadores,Centro de conferencias de 1899 metros cuadrados']

How do I merge items from a list avoiding repeated content inside the items?

Edit 4:
Simpler example of what I want to do:
I have a list like this:
sentences = ['Hello, how are','how are you','you doing?']
And I want to turn it into a string like this:
sentence = 'Hello, how are you doing?'
Any help is appreciated!
Original post:
I'm trying to get highlighted text out of a .pdf file and put it inside a .docx file with that same name.
Here's the code for it:
from typing import List, Tuple
import fitz # install with 'pip install pymupdf'
import os
from docx import Document
def _parse_highlight(annot: fitz.Annot, wordlist: List[Tuple[float, float, float, float, str, int, int, int]]) -> str:
points = annot.vertices
quad_count = int(len(points) / 4)
sentences = []
for i in range(quad_count):
# where the highlighted part is
r = fitz.Quad(points[i * 4: i * 4 + 4]).rect
words = [w for w in wordlist if fitz.Rect(w[:4]).intersects(r)]
sentences.append(" ".join(w[4] for w in words))
sentence = " ".join(sentences)
return sentence
def handle_page(page):
wordlist = page.getText("words") # list of words on page
wordlist.sort(key=lambda w: (w[3], w[0])) # ascending y, then x
separator = "PÁGINA NÚMERO " + str(page.number) + ": "
highlights = []
annot = page.firstAnnot
while annot:
if annot.type[0] == 8:
highlights.append(separator)
highlights.append(_parse_highlight(annot, wordlist))
document.add_paragraph(highlights)
annot = annot.next
return highlights
def main(filepath: str) -> List:
doc = fitz.open(filepath)
highlights = []
for page in doc:
highlights += handle_page(page)
return highlights
dir_files = [f for f in os.listdir(".") if os.path.isfile(os.path.join(".", f))]
print(dir_files)
document = Document()
for file in dir_files: # look at every file in the current directory
if file.endswith('.pdf'): # if it is a PDF, use it
print('Working on converting: ' + file)
main(file)
document.save(file.replace(".pdf",".docx"))
I have to say I didn't write the part for getting the text out of the highlights. I got it here.
The problem is the list it creates gets repeated items. Here's a sample of the output to the .docx file:
PÁGINA NÚMERO 0: En los primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras que se extiende a través del citoplasma (fig. 6-20). El citoesqueleto, revelado la presencia del citoesqueleto, una red de fibras que se extiende a través del citoplasma (fig. 6-20). El citoesqueleto, que desempena un papel importante en la organizacion a través del citoplasma (fig. 6-20). que desempena un papel importante en la organizacion estructuras y las actividades de la célula,
PÁGINA NÚMERO 0: En los primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras que se extiende a través del citoplasma (fig. 6-20). El citoesqueleto, revelado la presencia del citoesqueleto, una red de
As you can see it repeats the same thing more than once.
I think it's because my pdf is split in two like this:
But it would be an inconvinience to split every page in half and create a longer pdf. Another problem could be that I OCR'd this pdf and maybe it's causing issues (this is why the text output is slightly different from the pdf but I'm fine with that).
So I'm looking for a way to check if the "highlights" list has repeated items and delete them. Or maybe check before they get added to the list and not add them. But I'm not that experienced in programming so I'm asking for your help!
Any help is appreciated!
And sorry for any bad english!
Edit 1:
I've now tried doing this:
...
def main(filepath: str) -> List:
doc = fitz.open(filepath)
highlights = []
for page in doc:
highlights += handle_page(page)
highlights = set(highlights)
highlights = list(highlights)
document.add_paragraph(highlights)
return highlights
...
But it doesn't work. It even changes the order of the items because it deletes stuff that was added first and I don't want that.
Edit 2:
I think I found what's giving me trouble.
I did print(sentences) before they get joined into "sentence" and this is what I get:
['En los primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte', 'primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados', 'pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia', 'en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras', 'microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras que se extiende a través del citoplasma (fig. 6-20). El citoesqueleto,', 'revelado la presencia del citoesqueleto, una red de fibras que se extiende a través del citoplasma (fig. 6-20). El citoesqueleto, que desempena un papel importante en la organizacion', 'a través del citoplasma (fig. 6-20). que desempena un papel importante en la organizacion estructuras y las actividades de la célula,']
As you can see the items inside "sentences" contain one another so even if I used set(sentences) it wouldn't work. The OCR had something to do with that I'm pretty sure.
So now I think I need to shift my focus into crossreferencing each item inside "sentences".
Like when doing A+B-(A∩B)=C. This means C wouldn't have duplicates and, if the order is correct, would make a comprihensible sentence. But I'm completely blank in if there's even a way to accomplish this.
I also learned this to eliminate dupes and still keep the order of a list: list(dict.fromkeys())
Edit 3:
Only ruunning this code:
def _parse_highlight(annot: fitz.Annot, wordlist: List[Tuple[float, float, float, float, str, int, int, int]]) -> str:
points = annot.vertices
quad_count = int(len(points) / 4)
sentences = []
for i in range(quad_count):
# where the highlighted part is
r = fitz.Quad(points[i * 4: i * 4 + 4]).rect
words = [w for w in wordlist if fitz.Rect(w[:4]).intersects(r)]
sentences.append(" ".join(w[4] for w in words))
print(sentences)
sentence = " ".join(sentences)
print(sentence)
return sentence
def handle_page(page):
wordlist = page.getText("words") # list of words on page
wordlist.sort(key=lambda w: (w[3], w[0]))
separator = "PÁGINA NÚMERO " + str(page.number) + ": "
highlights = []
annot = page.firstAnnot
while annot:
if annot.type[0] == 8:
highlights.append(separator)
highlights.append(_parse_highlight(annot, wordlist))
annot = annot.next
return highlights
def main(filepath: str) -> List:
doc = fitz.open(filepath)
highlights = []
for page in doc:
highlights += handle_page(page)
print(highlights)
return highlights
main(example.pdf)
This is the only thing I higlighted:
Here's what the terminal says:
['El citoesqueleto es una red de fibras que organiza las estructuras', 'citoesqueleto es una red de que organiza las estructuras y las actividades', 'las estructuras y las actividades de la célula', 'En los primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte', 'primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados', 'pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia', 'en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras', 'microscopia 6ptica como en la microscopia revelado la presencia del citoesqueleto, extiende a través del citoplasma']
El citoesqueleto es una red de fibras que organiza las estructuras citoesqueleto es una red de que organiza las estructuras y las actividades las estructuras y las actividades de la célula En los primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras microscopia 6ptica como en la microscopia revelado la presencia del citoesqueleto, extiende a través del citoplasma
['PÁGINA NÚMERO 0: ', 'El citoesqueleto es una red de fibras que organiza las estructuras citoesqueleto es una red de que organiza las estructuras y las actividades las estructuras y las actividades de la célula En los primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte primeros tiempos de la microscopia electronica los bi- logos pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados pensaban que los organulos de una célula eucarionte flota- ban libremente en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia en el citosol. Pero los progresos realizados tanto en la microscopia 6ptica como en la microscopia electronica han revelado la presencia del citoesqueleto, una red de fibras microscopia 6ptica como en la microscopia revelado la presencia del citoesqueleto, extiende a través del citoplasma']
Now I see that some text I didn't highlight is also being turned into a "sentences" item. Again, I believe this to be the OCR at fault or maybe I could tune the pymupdf better idk.
You can use python set in order to remove duplicates. It should be done AFTER the loop and BEFORE the return
highlights = ['h1', 'h2', 'h1']
no_dups_highlights = list(set(highlights))
print(no_dups_highlights)
output
['h2', 'h1']
So set shuffles the members; you can use it, but only as a helper.
There are several ways to do this:
Use a set to keep track of what you've already seen:
seen = set()
filtered = []
for highlight in highlights:
if highlight not in seen:
filtered.append(highlight)
seen.add(highlight)
If you're using a sufficiently recent version of Python, dict maintains order:
filtered = list({highlight: None for highlight in highlights}.keys())
Ignore the theoretical slowness and just code it in the most straightforward way; it'll likely be fast enough in practice:
filtered = []
for highlight in highlights:
if highlight not in filtered:
filtered.append(higwhlight)
All these are for exact matching; if you end up needing approximate matching, you'll probably have to use the last approach anyway, with some sort of similarity measure.
I've implemented another method of getting the 'sentences' list out of the pdf and now it works as intended.
This is the code:
from typing import List, Tuple
import fitz
import os
from docx import Document
_threshold_intersection = 0.9
def _check_contain(r_word, points):
r = fitz.Quad(points).rect
r.intersect(r_word)
if r.getArea() >= r_word.getArea() * _threshold_intersection:
contain = True
else:
contain = False
return contain
def _parse_highlight(annot: fitz.Annot, wordlist: List[Tuple[float, float, float, float, str, int, int, int]]) -> str:
quad_points = annot.vertices
quad_count = int(len(quad_points) / 4)
sentences = ['' for i in range(quad_count)]
for i in range(quad_count):
points = quad_points[i * 4: i * 4 + 4]
words = [
w for w in wordlist if
_check_contain(fitz.Rect(w[:4]), points)
]
sentences[i] = ' '.join(w[4] for w in words)
sentence = ' '.join(sentences)
document.add_paragraph(sentence)
return sentence
def handle_page(page):
wordlist = page.getText("words")
wordlist.sort(key=lambda w: (w[3], w[0]))
highlights = []
annot = page.firstAnnot
while annot:
if annot.type[0] == 8:
highlights.append(_parse_highlight(annot, wordlist))
annot = annot.next
return highlights
def main(filepath: str) -> List:
doc = fitz.open(filepath)
highlights = []
for page in doc:
document.add_paragraph("Page Number " + str(page.number+1) + ": ")
highlights += handle_page(page)
return highlights
dir_files = [f for f in os.listdir(".") if os.path.isfile(os.path.join(".", f))]
document = Document()
for file in dir_files:
if file.endswith('.pdf'):
print('Working on converting: ' + file)
main(file)
document.save(file.replace(".pdf",".docx"))
Got this new method here.

Regular expression findall python

I have text which look like that
{"#context":"http://schema.org","#type":"Recipe","name":"Tartelette aux fraises et rhubarb'curd","recipeCategory":"tarte aux fraises","image":"https://assets.afcdn.com/recipe/20160527/8530_w1024h768c1cx1941cy2911.jpg","datePublished":"2012-10-10T08:48:00+02:00","prepTime":"PT90M","cookTime":"PT15M","totalTime":"PT105M","recipeYield":"4 personnes","recipeIngredient":["250 g de fraises","150 g de farine","45 g de beurre","40 g de sucre","1 oeuf","1 pinc\u00e9e de sel","20 cl de rhubarbe (r\u00e9cup\u00e9r\u00e9 de ma conception de compote)","3 oeufs","75 g de sucre","1 cuill\u00e8re \u00e0 soupe de ma\u00efzena"],"recipeInstructions":[{"#type":"HowToStep","text":"Pour 4 tartelettes ( ou une grande tarte mais je pr\u00e9f\u00e8re les tartelettes, la p\u00e2te sabl\u00e9e \u00e9tant difficile \u00e0 couper :)) "},{"#type":"HowToStep","text":"Pr\u00e9parer la p\u00e2te sabl\u00e9e : "},{"#type":"HowToStep","text":"Couper le beurre en petits morceaux."},{"#type":"HowToStep","text":"Mettre tous les ingr\u00e9dients dans un saladier et tout m\u00e9langer \u00e0 la main ( ou au robot) jusqu'\u00e0 former une boule homog\u00e8ne. La r\u00e9server au frais au moins 1h pour pouvoir mieux l'\u00e9taler."},{"#type":"HowToStep","text":"Pendant que la p\u00e2te sabl\u00e9es pose, pr\u00e9parer le rhubarb'curd : "},{"#type":"HowToStep","text":"M\u00e9langer le sucre avec le jus de rhubarbe sur feu doux, jusqu\u2019\u00e0 ce que le sucre soit fondu. "},{"#type":"HowToStep","text":"A part, dans un bol (qui pourra aller au bain marie dans l'\u00e9tape suivante), battre la ma\u00efzena avec 1 oeuf. Lorsqu\u2019elle est bien dissoute, incorporer les 2 autres oeufs, toujours en fouettant."},{"#type":"HowToStep","text":"Incorporer ensuite le jus de rhubarbe chaud en fouettant bien, le m\u00e9lange commence \u00e0 \u00e9paissir. Placer le bol au bain marie et faire \u00e9paissir sur feu doux tout en fouettant tr\u00e8s r\u00e9guli\u00e8rement."},{"#type":"HowToStep","text":"Une fois qu\u2019elle est bien \u00e9paisse, transf\u00e9rer dans un autre bol ou saladier pour la refroidir. "},{"#type":"HowToStep","text":"Pendant que le curd refroidit, cuire la p\u00e2te sabl\u00e9e \u00e0 blanc. Etaler la p\u00e2te sabl\u00e9e et la r\u00e9partir dans les 4 moules \u00e0 tartelette (ou dans un grand moule \u00e0 tarte). Puis enfourner entre 10 et 15 min (en fonction de votre four) \u00e0 200\u00b0C (thermostat 6-7)."},{"#type":"HowToStep","text":"Laisser refroidir les fonds une bonne demi heure."},{"#type":"HowToStep","text":"Monter les tartelettes : "},{"#type":"HowToStep","text":"- mettre une couche de rhubarb' curd dans les fonds de tarte"},{"#type":"HowToStep","text":"- laver et \u00e9queuter les fraises"},{"#type":"HowToStep","text":"- les couper en 2 et les disposer sur le rhubarb'curd."},{"#type":"HowToStep","text":"- conserver au frais avant de servir"}],
In the field RecipeInstructions I need to get everything write after "text": . I never used regular expression and I'm a little bit lost.
This looks like a json object but doesn't have [] around it to make it an actual list. You should be able to convert it into a Python native list of dictionaries and navigate it:
import json
recipe = json.loads('[' + your_text + ']')
steps = [obj["text"] for obj in recipe if obj.get("#type") == "HowToStep"]
What worries me though is that unless you truncated your text to post here, this may not be a well formed json. In which case you cannot use the above code and instead use regular expressions like this:
import re
regex = r"\"text\":\"([^\"]*)\""
matches = re.findall(regex, your_text)
'matches' should now be a list of all the text elements.
Curious about how this regex works? Here's a simulator

Converting regexp pattern to lowercase

I have some XML text like this:
text = '<sp> <speaker>T<seg rend="small">ARSIS</seg>. </speaker> <p>—Adelante, Señora. Gracias á la luz rosada, franquearemos sin tropezones este ingrato sendero.</p> </sp> <sp> <speaker>L<seg rend="small">A</seg> M<seg rend="small">ADRE</seg>. </speaker> <p>—La llovizna nos coge ahora de cara… Yo no la temo. Tengo mi rostro bien curtido para estas inclemencias que hacen á mis hijos duros, y tan insensibles al frío como al calor. Tú también te has endurecido, según veo, y te has dejado en los aires sutiles y en los ardores del sol tu antigua carita de galancete afeminado.</p>'
I want everything in the <seg rend="small"> to become lowercase, like:
<sp> <speaker>T<seg rend="small">arsis</seg>. </speaker> <p>—Adelante, Señora. Gracias á la luz rosada, franquearemos sin tropezones este ingrato sendero.</p> </sp> <sp> <speaker>L<seg rend="small">a</seg> M<seg rend="small">adre</seg>. </speaker> <p>—La llovizna nos coge ahora de cara… Yo no la temo. Tengo mi rostro bien curtido para estas inclemencias que hacen á mis hijos duros, y tan insensibles al frío como al calor. Tú también te has endurecido, según veo, y te has dejado en los aires sutiles y en los ardores del sol tu antigua carita de galancete afeminado.</p> </sp> <sp> <speaker>T<seg rend="small">arsis</seg>. </speaker> <p>—En los días ásperos de la Aldehuela empecé á soltar mi máscara de cera, y cambié los goznes quebradizos de mi máquina corporal por otros de acero.</p> </sp> <sp> <speaker>L<seg rend="small">a</seg> M<seg rend="small">adre</seg>. </speaker> <p>—Al nombrar la Aldehuela traes á mi memoria algo que tenía que decirte, y es cosa en verdad lamentable. ¿Sabes que ha muerto el pobre José Caminero?</p> </sp>
I have tried different variants of something like this in Python:
for f in re.findall(r'<seg rend="small">([^<]*?)</seg>', text):
text = text.replace(f, f.lower())
But it doesn't work and I get weird results like <seg rend="small">aDRE</seg>, no idea why. Could please anyone help me? Thanks in advance!
You may use regex..
>>> txt = 'foo <seg rend="small">ARSIS</seg> bar'
>>> import re
>>> re.sub(r'(<seg\s+rend\s*=\s*"small">)(.*?)(?=</seg>)', lambda m: m.group(1) + m.group(2).lower(), txt)
'foo <seg rend="small">arsis</seg> bar'
>>>
First of all, do not parse HTML with regex. That being said, you could use lxml:
from lxml import html
text = '<sp> <speaker>T<seg rend="small">ARSIS</seg>. </speaker> <p>—Adelante, Señora. Gracias á la luz rosada, franquearemos sin tropezones este ingrato sendero.</p> </sp> <sp> <speaker>L<seg rend="small">A</seg> M<seg rend="small">ADRE</seg>. </speaker> <p>—La llovizna nos coge ahora de cara… Yo no la temo. Tengo mi rostro bien curtido para estas inclemencias que hacen á mis hijos duros, y tan insensibles al frío como al calor. Tú también te has endurecido, según veo, y te has dejado en los aires sutiles y en los ardores del sol tu antigua carita de galancete afeminado.</p>'
tree = html.fromstring(text)
results = [x.lower() for x in tree.xpath('//seg[#rend="small"]/text()')]
print results
Output:
['arsis', 'a', 'adre']

How can I detect whether a given line in a file is a proper English sentence?

I need to detect if a given "line" in a file is an English sentence or not. I am using Python. An approximate answer would do. I understand this is an NLP question but is there a lightweight tool that gives a reasonable approximation? I do not want to use a full-fledged NLP toolkit for this though if that is the only way then it is fine.
If NLP toolkit is the answer then the one that I am reading about is the Natural Language Toolkit. If anyone has a simple example on how to detect a sentence handy, please point me to it.
Perhaps you are looking for Punkt Tokenizer from the nltk library, which can provide you the english sentences from a given text. You can then act upon the sentences by doing a grammar check(pointed out by Acron)
Currently, computer software cannot tell you whether a given string of tokens is a grammatical English sentence with any reasonable degree of reliability. You might, however, look into Amazon's Mechanical Turk. If you present the sentence to five native English speakers, and the majority of them say it is grammatical, you can assume it is with a reasonable level of certainty.
Of course, while Mechanical Turk does have a Web Services API and thus could be used from Python, it will not be real-time.
You can use Python Reverend. It has less the 400 lines of code. Take a look in how can you use it:
>>> from thomas import Bayes
>>> guesser = Bayes()
>>> guesser.train("en" u"a about above after again against all am an and any are aren't as at be because been before being below between both but by can't cannot could couldn't did didn't do does doesn't doing don't down during each few for from further had hadn't has hasn't have haven't having he he'd he'll he's her here here's hers herself him himself his how how's i i'd i'll i'm i've if in into is isn't it it's its itself let's me more most mustn't my myself no nor not of off on once only or other ought our ours ourselves out over own same shan't she she'd she'll she's should shouldn't so some such than that that's the their theirs them themselves then there there's these they they'd they'll they're they've this those through to too under until up very was wasn't we we'd we'll we're we've were weren't what what's when when's where where's which while who who's whom why why's with won't would wouldn't you you'd you'll you're you've your yours yourself yourselves")
>>> guesser.train("pt" u"último é acerca agora algmas alguns ali ambos antes apontar aquela aquelas aquele aqueles aqui atrás bem bom cada caminho cima com como comprido conhecido corrente das debaixo dentro desde desligado deve devem deverá direita diz dizer dois dos e ela ele eles em enquanto então está estão estado estar estará este estes esteve estive estivemos estiveram eu fará faz fazer fazia fez fim foi fora horas iniciar inicio ir irá ista iste isto ligado maioria maiorias mais mas mesmo meu muito muitos nós não nome nosso novo o onde os ou outro para parte pegar pelo pessoas pode poderá podia por porque povo promeiro quê qual qualquer quando quem quieto são saber sem ser seu somente têm tal também tem tempo tenho tentar tentaram tente tentei teu teve tipo tive todos trabalhar trabalho tu um uma umas uns usa usar valor veja ver verdade verdadeiro você")
>>> guesser.train("es" u"un una unas unos uno sobre todo también tras otro algún alguno alguna algunos algunas ser es soy eres somos sois estoy esta estamos estais estan como en para atras porque por qué estado estaba ante antes siendo ambos pero por poder puede puedo podemos podeis pueden fui fue fuimos fueron hacer hago hace hacemos haceis hacen cada fin incluso primero desde conseguir consigo consigue consigues conseguimos consiguen ir voy va vamos vais van vaya gueno ha tener tengo tiene tenemos teneis tienen el la lo las los su aqui mio tuyo ellos ellas nos nosotros vosotros vosotras si dentro solo solamente saber sabes sabe sabemos sabeis saben ultimo largo bastante haces muchos aquellos aquellas sus entonces tiempo verdad verdadero verdadera cierto ciertos cierta ciertas intentar intento intenta intentas intentamos intentais intentan dos bajo arriba encima usar uso usas usa usamos usais usan emplear empleo empleas emplean ampleamos empleais valor muy era eras eramos eran modo bien cual cuando donde mientras quien con entre sin trabajo trabajar trabajas trabaja trabajamos trabajais trabajan podria podrias podriamos podrian podriais yo aquel")
>>> guesser.guess(u'what language am i speaking')
>>> [('en', 0.99990000000000001)]
>>> guesser.guess(u'que língua eu estou falando')
>>> [('pt', 0.99990000000000001)]
>>> guesser.guess(u'en qué idioma estoy hablando')
>>> [('es', 0.99990000000000001)]
You should be very careful on choosing the best training data for your needs. Just for giving an idea to you I collect some stop words from English, Portuguese and Spanish.

Categories