Estoy aprendiendo Python y estoy luchando con encontrar una palabra exacta en cada cadena en una lista de cadenas. Disculpas si esta es una pregunta ya hecha para esta situación.

Así es como se ve mi código hasta ahora:

with open('text.txt') as f:
  lines = f.readlines()
  lines = [line.rstrip('\n') for line in open('text.txt')]


keyword = input("Enter a keyword: ")

matching = [x for x in lines if keyword.lower() in x.lower()]

match_count = len(matching)

print('\nNumber of matches: ', match_count, '\n')
print(*matching, sep='\n')

En este momento, coincidencia devolverá todas las cadenas que contengan la palabra, no las cadenas que contengan la palabra exacta. Por ejemplo, si ingreso 'local' como la palabra clave, las cadenas con 'localmente' y 'localizado' además de 'local' serán devueltas cuando solo quiero que solo se devuelvan instancias de 'local'.

He intentado:

match_test = re.compile(r"\b" + keyword+ r"\b")

match_test = ('\b' + keyword + '\b')

match_test = re.compile('?:^|\s|$){0}'.format(keyword))


matching = [x for x in lines if keyword.lower() == x.lower()]

matching = [x for x in lines if keyword.lower() == x.lower().strip()]

Y ninguno de ellos funcionó bien, así que estoy un poco atascado. ¿Cómo tomo la palabra clave ingresada por el usuario y luego devuelvo todas las cadenas en una lista que contiene esa palabra clave exacta?

Gracias

1
ksm 6 oct. 2019 a las 08:27

5 respuestas

La mejor respuesta

in significa contenido en , 'abc' in 'abcd' es True. Para la coincidencia exacta use ==

matching = [x for x in lines if keyword.lower() == x.lower()]

Es posible que también necesite eliminar espacios \ líneas nuevas

matching = [x for x in lines if keyword.lower().strip() == x.lower().strip()]

Editar:

Para encontrar una línea que contenga la palabra clave, puede usar bucles

matches = []
for line in lines:
    for string in line.split(' '):
        if string.lower().strip() == keyword.lower().strip():
            matches.append(line)
3
Guy 6 oct. 2019 a las 06:27

Tu primera prueba parece estar en el camino correcto

Usando entrada:

import re
lines = [
  'local student',
  'i live locally',
  'keyboard localization',
  'what if local was in middle',
  'end with local',
]
keyword = 'local'

Prueba esto:

pattern = re.compile(r'.*\b{}\b'.format(keyword.lower()))
matching = [x for x in lines if pattern.match(x.lower())]
print(matching)

Salida:

['local student', 'what if local was in middle', 'end with local']

pattern.match devolverá la primera instancia de la coincidencia de expresiones regulares o None. Al usar esto como su condición if, se filtrarán las cadenas que coincidan con la palabra clave completa en algún lugar. Esto funciona porque \b coincide con el principio / final de las palabras. .* funciona para capturar los caracteres que pueden aparecer al comienzo de la línea antes de que aparezca su palabra clave.

Para obtener más información sobre el uso de re de Python, consulte los documentos aquí: https: / /docs.python.org/3.8/library/re.html

0
jmullercuber 3 nov. 2019 a las 04:20

Puedes probar

pattern = re.compile(r"\b{}\b".format(keyword))
match_test = pattern.search(line)

Como se muestra en Python - Concat dos cadenas sin formato con un nombre de usuario

-1
abhilb 6 oct. 2019 a las 05:37

Encuentre mi solución que debe coincidir solo local entre el siguiente texto mencionado en el archivo de texto. Utilicé la expresión regular de búsqueda para encontrar la instancia que solo tiene 'local' en la cadena y no se buscarán otras cadenas que contengan local.

Variables proporcionadas en el archivo de texto:

local
localized
locally
local
local diwakar
       local
   local@#!

Código para buscar solo instancias de 'local' en el archivo de texto:

import os
import sys
import time
import re

with open('C:/path_to_file.txt') as f:
    for line in f:
        a = re.search(r'local\W$', line) 
        if a:
            print(line)

Salida

local

local

       local

Avísame si esto es lo que estabas buscando

0
Diwakar SHARMA 6 oct. 2019 a las 07:44

Este método evita tener que leer todo el archivo en la memoria. También trata casos como "LocaL" o "LOCAL" suponiendo que desea capturar todas esas variantes. Sin embargo, hay un poco de sobrecarga de rendimiento al hacer la cadena temporal cada vez que se lee la línea:

import re 

reader(filename, target):
     #this regexp matches a word at the front, end or in the middle of a line stripped 
     #of all punctuation and other non-alpha, non-whitespace characters:
     regexp = re.compile(r'(^| )' + target.lower() + r'($| )')
     with open(filename) as fin:
         matching = []
         #read lines one at at time:
         for line in fin:
             line = line.rstrip('\n')
             #generates a line of lowercase and whitespace to test against
             temp = ''.join([x.lower() for x in line if x.isalpha() or x == ' '])
             print(temp)
             if regexp.search(temp):
                 matching.append(line) #store unaltered line
         return matching

Dadas las siguientes pruebas:

localmente local! localizado

localmente localizada no localizada

La palabra mágica es local.

Localizada o no local o LOCAL

Esto se devuelve:

['locally local! localized',
 'the magic word is Local.',
 'Localized or nonlocal or LOCAL']
0
neutrino_logic 6 oct. 2019 a las 07:08
58254472