una signos separar quitar puntuacion primer palabra letras especiales espacios eliminar como caracteres caracter cadena python string split

python - separar - Dividir una cuerda en palabras y signos de puntuación



quitar de una cadena python (9)

Intento dividir una cadena en palabras y signos de puntuación, agregando la puntuación a la lista producida por la división.

Por ejemplo:

>>> c = "help, me" >>> print c.split() [''help,'', ''me'']

Como realmente quiero que se vea la lista es:

[''help'', '','', ''me'']

Entonces, quiero que la secuencia se divida en espacios en blanco con la puntuación separada de las palabras.

Intenté analizar la cadena primero y luego ejecutar la división:

>>> for character in c: ... if character in ".,;!?": ... outputCharacter = " %s" % character ... else: ... outputCharacter = character ... separatedPunctuation += outputCharacter >>> print separatedPunctuation help , me >>> print separatedPunctuation.split() [''help'', '','', ''me'']

Esto produce el resultado que quiero, pero es dolorosamente lento en archivos grandes.

¿Hay alguna manera de hacer esto de manera más eficiente?


¿Has intentado usar una expresión regular?

http://docs.python.org/library/re.html#re-syntax

Por cierto. ¿Por qué necesitas el "," en el segundo? Sabrá que después de cada texto se escribe, es decir,

[0]

","

[1]

","

Entonces, si desea agregar el "," puede hacerlo después de cada iteración cuando usa el conjunto.


Aquí está mi entrada.

Tengo mis dudas sobre qué tan bien se mantendrá en el sentido de eficiencia, o si atrapa todos los casos (observe el "!!!" agrupados, esto puede o no ser algo bueno).

>>> import re >>> import string >>> s = "Helo, my name is Joe! and i live!!! in a button; factory:" >>> l = [item for item in map(string.strip, re.split("(/W+)", s)) if len(item) > 0] >>> l [''Helo'', '','', ''my'', ''name'', ''is'', ''Joe'', ''!'', ''and'', ''i'', ''live'', ''!!!'', ''in'', ''a'', ''button'', '';'', ''factory'', '':''] >>>

Una optimización obvia sería compilar la regex previa (usando re.compile) si va a hacer esto línea por línea.


Aquí hay una actualización menor de su implementación. Si estás tratando de hacer algo más detallado, te sugiero que busques en el NLTK lo que sugirió le dorfier.

Esto podría ser solo un poco más rápido ya que '''' .join () se usa en lugar de + =, que se sabe que es más rápido .

import string d = "Hello, I''m a string!" result = [] word = '''' for char in d: if char not in string.whitespace: if char not in string.ascii_letters + "''": if word: result.append(word) result.append(char) word = '''' else: word = ''''.join([word,char]) else: if word: result.append(word) word = '''' print result [''Hello'', '','', "I''m", ''a'', ''string'', ''!'']


Aquí hay una versión compatible con Unicode:

re.findall(r"/w+|[^/w/s]", text, re.UNICODE)

La primera alternativa captura secuencias de caracteres de palabras (como se define por unicode, por lo que "currículum" no se convertirá en [''r'', ''sum''] ); el segundo atrapa caracteres individuales sin palabra, ignorando el espacio en blanco.

Tenga en cuenta que, a diferencia de la respuesta superior, esto trata la comilla simple como puntuación separada (por ejemplo, "I''m" -> [''I'', "''", ''m''] ). Esto parece ser estándar en PNL, así que lo considero una característica.


Creo que puedes encontrar toda la ayuda que puedas imaginar en el NLTK , especialmente porque estás usando Python. Hay una buena discusión exhaustiva sobre este tema en el tutorial.


En la sintaxis de expresiones regulares estilo perl, /b coincide con un límite de palabras. Esto debería ser útil para hacer una división basada en expresiones regulares.

editar: me han informado por hop que "coincidencias vacías" no funcionan en la función de división del módulo re de Python. Dejaré esto aquí como información para que cualquier otra persona quede perpleja por esta "característica".


Esta es más o menos la manera de hacerlo:

>>> import re >>> re.findall(r"[/w'']+|[.,!?;]", "Hello, I''m a string!") [''Hello'', '','', "I''m", ''a'', ''string'', ''!'']

El truco es no pensar dónde dividir la cadena, sino qué incluir en las fichas.

Advertencias:

  • El guión bajo (_) se considera un carácter interno. Reemplace / w, si no quiere eso.
  • Esto no funcionará con comillas (únicas) en la cadena.
  • Ponga cualquier signo de puntuación adicional que quiera usar en la mitad derecha de la expresión regular.
  • Todo lo que no se menciona explícitamente en el re se descarta silenciosamente.

Prueba esto:

string_big = "One of Python''s coolest features is the string format operator This operator is unique to strings" my_list =[] x = len(string_big) poistion_ofspace = 0 while poistion_ofspace < x: for i in range(poistion_ofspace,x): if string_big[i] == '' '': break else: continue print string_big[poistion_ofspace:(i+1)] my_list.append(string_big[poistion_ofspace:(i+1)]) poistion_ofspace = i+1 print my_list


Se me ocurrió una forma de tokenizar todas las palabras y patrones /W+ usando /b que no necesita codificación rígida:

>>> import re >>> sentence = ''Hello, world!'' >>> tokens = [t.strip() for t in re.findall(r''/b.*?/S.*?(?:/b|$)'', sentence)] [''Hello'', '','', ''world'', ''!'']

Aquí .*?/S.*? es un patrón que coincide con cualquier cosa que no sea un espacio y $ se agrega para que coincida con el último token en una cadena si es un símbolo de puntuación.

Sin embargo, tenga en cuenta lo siguiente: esto agrupará la puntuación que consiste en más de un símbolo:

>>> print [t.strip() for t in re.findall(r''/b.*?/S.*?(?:/b|$)'', ''"Oh no", she said'')] [''Oh'', ''no'', ''",'', ''she'', ''said'']

Por supuesto, puedes encontrar y dividir dichos grupos con:

>>> for token in [t.strip() for t in re.findall(r''/b.*?/S.*?(?:/b|$)'', ''"You can", she said'')]: ... print re.findall(r''(?:/w+|/W)'', token) [''You''] [''can''] [''"'', '',''] [''she''] [''said'']