¿Cómo puedo realizar una búsqueda de cadena inversa en Excel sin usar VBA?

165

Tengo una hoja de cálculo de Excel que contiene una lista de cadenas. Cada cadena está compuesta por varias palabras, pero el número de palabras en cada cadena es diferente.

Usando las funciones integradas de Excel (sin VBA), ¿hay alguna manera de aislar la última palabra en cada cadena?

Ejemplos:

  ¿Estás clasificado como humano? -> humano?
Negativo, soy una paleta de carne -> paleta
                  Aziz! ¡Ligero! -> ¡Luz!
e.James
fuente
44
Me pregunto por qué tiene la restricción artificial sin VBA.
EBGreen
3
Puedo resolverlo fácilmente con VBA, pero tengo curiosidad por saber si hay una solución que no sea VBA. VBA tiende a tener penalizaciones de rendimiento para grandes conjuntos de datos.
e.James
Como de costumbre, dos respuestas realmente se destacan, y me cuesta decidir cuál seleccionar como la respuesta correcta. En este caso, tanto Jon como BradC (con la ayuda de Brad) han encontrado soluciones correctas y funcionales.
e.James
He seleccionado la solución de BradC porque parece ser la más elegante de las dos, y él proporciona una explicación práctica de la función.
e.James
Es difícil responder a su pregunta correctamente si no indica qué hace que VBA sea inapropiado (ya que puede escribir sus propias macros y funciones en VBA, lo que lo hace equivalente a las funciones integradas).
dkretz

Respuestas:

208

Este está probado y funciona (según la publicación original de Brad):

=RIGHT(A1,LEN(A1)-FIND("|",SUBSTITUTE(A1," ","|",
     LEN(A1)-LEN(SUBSTITUTE(A1," ","")))))

Si sus cadenas originales pudieran contener una tubería "|" carácter, luego reemplace ambos en lo anterior con algún otro carácter que no aparecerá en su fuente. (Sospecho que el original de Brad estaba roto porque se eliminó un carácter no imprimible en la traducción).

Bonificación: cómo funciona (de derecha a izquierda):

LEN(A1)-LEN(SUBSTITUTE(A1," ",""))- Conteo de espacios en la cadena original
SUBSTITUTE(A1," ","|", ... )- Reemplaza solo el espacio final con un |
FIND("|", ... )- Encuentra la posición absoluta de ese reemplazado |(ese fue el espacio final)
Right(A1,LEN(A1) - ... ))- Devuelve todos los caracteres después de eso|

EDITAR: para tener en cuenta el caso en el que el texto de origen no contiene espacios, agregue lo siguiente al comienzo de la fórmula:

=IF(ISERROR(FIND(" ",A1)),A1, ... )

haciendo toda la fórmula ahora:

=IF(ISERROR(FIND(" ",A1)),A1, RIGHT(A1,LEN(A1) - FIND("|",
    SUBSTITUTE(A1," ","|",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))))))

O puede usar la =IF(COUNTIF(A1,"* *")sintaxis de la otra versión.

Cuando la cadena original puede contener un espacio en la última posición, agregue una función de recorte mientras cuenta todos los espacios: Haga que la función sea la siguiente:

=IF(ISERROR(FIND(" ",B2)),B2, RIGHT(B2,LEN(B2) - FIND("|",
    SUBSTITUTE(B2," ","|",LEN(TRIM(B2))-LEN(SUBSTITUTE(B2," ",""))))))
BradC
fuente
1
No puedo agradecerles lo suficiente. También necesitaba el resto de la cadena, así que simplemente cambiar = DERECHA a = IZQUIERDA y eliminar LEN (A1) - me permitió obtener el resto. Pero gracias por hacer todo el trabajo inicial de la pierna :)
Luke Duddridge
44
+1: tendré que recordar el truco "LEN (A1) -LEN (SUBSTITUTE (A1," "," "))" para obtener el número de instancias de un personaje
anschauung
2
Excelente solucion! El único problema es que Excel localiza los nombres de las funciones, por lo que debe volver a escribir la fórmula para el Excel que no está en inglés. Aquí está la variante reescrita para la rusa: = ПРАВСИМВ (A1; ДЛСТР (A1) -ПОИСК ("|"; ПОДСТАВИТЬ (A1; ""; "|"; ДЛСТР (A1) -ДЛСТР (ПОДСТАВИТЬ (A1; ""; "")))))
Michael Pliskin
Esta respuesta se rompe en cadenas que contienen espacios consecutivos.
somewhatsapient
1
Recomendaría dividir las fórmulas en columnas temporales (puede ocultarlas más adelante). Es muy útil para depurar casos especiales.
wisbucky
84

Esta es la técnica que he usado con gran éxito:

=TRIM(RIGHT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100))

Para obtener la primera palabra en una cadena, simplemente cambie de DERECHA a IZQUIERDA

=TRIM(LEFT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100))

Además, reemplace A1 por la celda que contiene el texto.

Jerry Beaucaire
fuente
2
Funciona para mí: acabo de reemplazar el primero " "con mi delimitador. Los dos 100s parecen limitarlo a una cadena de 100 caracteres si no me equivoco
Benjineer
1
Si usamos un delimitador diferente, también debemos eliminarlo al final, por ejemplo=TRIM(SUBSTITUTE(RIGHT(SUBSTITUTE(A1, ".", REPT(".", 100)), 100), ".", ""))
dumbledad
77
Método muy inteligente. Lo que hace es reemplazar cada espacio con 100 espacios, luego devolver los últimos 100 caracteres sin espacios iniciales / finales.
Zenadix
@Benjineer Creo que funciona para cadenas de más de 100 caracteres. Los 100 caracteres limitan el tamaño de una sola palabra. Estás tomando los cien caracteres a la derecha (o a la izquierda) ... si una palabra de 101 caracteres tuviera un problema, pero si una cadena total de 100 caracteres ... con 3 espacios ... sería acolchado a aproximadamente una cadena de 400 caracteres y aún funciona. A Jerry Beaucaire - Muy elegante, gracias.
Tin Bum
22

Una versión más robusta de la respuesta de Jerry:

=TRIM(RIGHT(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))), LEN(TRIM(A1))))

Eso funciona independientemente de la longitud de la cadena, los espacios iniciales o finales, o lo que sea, y sigue siendo bastante corto y simple.

Joe Finkle
fuente
2
Es una excelente fórmula. Modifiqué la fórmula =TRIM(RIGHT(SUBSTITUTE(TRIM(A1), ".", REPT(" ", LEN(TRIM(A1)))), LEN(TRIM(A1))))para obtener la extensión del archivo.
Adarsh ​​Madrecha
2
Uno más le SUBSTITUTEpermite trabajar para cualquier personaje, no solo espacios. =TRIM(SUBSTITUTE(RIGHT(SUBSTITUTE(TRIM(A1),"/",REPT("/",LEN(TRIM(A1)))),LEN(TRIM(A1))),"/","")), donde "/" es el carácter delimitador.
PProteus
@Joefinkle, esta es una solución realmente concisa e inteligente. Funciona bastante bien, sólo para mencionar que si el delimitador es una cadena que no funciona bien en todos los casos, aquí un ejemplo de un delimitador: " ; "(punto y coma rodeado por espacios) con el valor de entrada: "Technology Sprint 24 ; Sprint 4"devuelve: "; Sprint 4". Estoy usando la solución adaptada por: @PProteus.
David Leal
Si el delimitador es una cadena, una posible solución sería reemplazarlo antes por algún carácter especial, por ejemplo, reemplazando en la fórmula @PProteus TRIM(A1)por: TRIM(SUBSTITUTE(A1, "strDelimeter", ";"))en todos los lugares, para tener un nuevo delimitador de caracteres: ";"o incluso mejor usando la char()función para encontrar algún personaje realmente inesperado.
David Leal
1
@PProteus, no necesita la TRIMfunción después de agregar el segundo SUBSTITUTEpara la solución de carácter único de caso general. La fórmula proporciona el resultado esperado eliminando esta parte:=SUBSTITUTE(RIGHT(SUBSTITUTE(TRIM(A1),";",REPT(";",LEN(TRIM(A1)))),LEN(TRIM(A1))),";","")
David Leal
13

Encontré esto en google, probé en Excel 2003 y funciona para mí:

=IF(COUNTIF(A1,"* *"),RIGHT(A1,LEN(A1)-LOOKUP(LEN(A1),FIND(" ",A1,ROW(INDEX($A:$A,1,1):INDEX($A:$A,LEN(A1),1))))),A1)

[editar] No tengo suficiente representante para comentar, así que este parece el mejor lugar ... La respuesta de BradC tampoco funciona con espacios finales o celdas vacías ...
[2da edición] en realidad, no funciona para palabras sueltas tampoco ...

Jon
fuente
La solución más cercana todavía, pero agregaría un Trim () ya que un espacio final lo romperá.
EBGreen
Es cierto, probablemente sea más fácil recortar () en una celda intermedia y luego aplicar la fórmula anterior a la celda intermedia. Además, escupe 0 si la celda está vacía, por lo que también podría envolverse con isblank ()
Jon
3
=RIGHT(TRIM(A1),LEN(TRIM(A1))-FIND(CHAR(7),SUBSTITUTE(" "&TRIM(A1)," ",CHAR(7),
LEN(TRIM(A1))-LEN(SUBSTITUTE(" "&TRIM(A1)," ",""))+1))+1)

Esto es muy robusto: funciona para oraciones sin espacios, espacios iniciales / finales, múltiples espacios, múltiples espacios iniciales / finales ... y utilicé char (7) para el delimitador en lugar de la barra vertical "|" en caso de que sea un elemento de texto deseado.

Mark Main
fuente
Funciona para mí en Excel 2010. Gracias
Rudiger Wolf
2

Esto es muy limpio y compacto, y funciona bien.

{=RIGHT(A1,LEN(A1)-MAX(IF(MID(A1,ROW(1:999),1)=" ",ROW(1:999),0)))}

No es una trampa de error para espacios o una palabra, pero eso es fácil de agregar.

Editar:
maneja espacios finales, una sola palabra y escenarios de celda vacía. No he encontrado una manera de romperlo.

{=RIGHT(TRIM(A1),LEN(TRIM(A1))-MAX(IF(MID(TRIM(A1),ROW($1:$999),1)=" ",ROW($1:$999),0)))}
gabrielu
fuente
Frio. ¡Ese es un uso realmente interesante de las funciones de matriz! No esperaba obtener otra respuesta después de tanto tiempo. Gracias por compartir.
e.James
2
=RIGHT(A1,LEN(A1)-FIND("`*`",SUBSTITUTE(A1," ","`*`",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))))) 
Cody Gray
fuente
¿Lo probaste? No funciona para mí con "¿Estás clasificado como humano?"
Ed Guiness
No, no funciona. Sin embargo, tiene algunos elementos interesantes. LEN (A1) -LEN (SUBSTITUTE (A1, "", "") le da el recuento de espacios en la cadena.
BradC
Esa es una función interesante. Lástima que no funcione. Me gusta el truco para poder contar la cantidad de espacios.
e
@Brad: edité tu publicación para mostrar los * caracteres. El original no los imprimió correctamente. Con estos en su lugar, funciona. +1
e.James
2

Para agregar a las respuestas de Jerry y Joe, si desea encontrar el texto ANTES de la última palabra, puede usar:

=TRIM(LEFT(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))), LEN(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))))-LEN(TRIM(A1))))

Con 'My little cat' en A1 daría como resultado 'My little cat' (donde Joe y Jerry's le darían 'cat'

De la misma manera que Jerry y Joe aíslan la última palabra, esto solo pone todo a la izquierda de eso (luego lo recorta)

Andrew B
fuente
1

Imagina que la cuerda se puede revertir. Entonces es realmente fácil. En lugar de trabajar en la cadena:

"My little cat" (1)

usted trabaja con

"tac elttil yM" (2)

Con =LEFT(A1;FIND(" ";A1)-1)en A2 obtienes "My"con (1) y "tac"con (2), que se invierte"cat" , la última palabra en (1).

Hay algunos VBA para revertir una cadena. Prefiero la función pública de VBA ReverseString.

Instale lo anterior como se describe. Luego, con su cadena en A1, por ejemplo, "My little cat"y esta función en A2:

=ReverseString(LEFT(ReverseString(A1);IF(ISERROR(FIND(" ";A1));
  LEN(A1);(FIND(" ";ReverseString(A1))-1))))

lo verás "cat"en A2.

El método anterior supone que las palabras están separadas por espacios en blanco. La IFcláusula es para celdas que contienen palabras simples = sin espacios en blanco en la celda. Nota: TRIMy CLEANla cadena original también son útiles. En principio, invierte toda la cadena desde A1 y simplemente encuentra el primer espacio en blanco en la cadena invertida que está al lado de la última palabra (invertida) (es decir, "tac "). LEFTelige esta palabra y otra inversión de cadena reconstituye el orden original de la palabra ( " cat"). Al -1final de laFIND declaración elimina el espacio en blanco.

La idea es que es fácil de extraer la primera (!) Palabra de una cadena con LEFTe FINDing el primer espacio en blanco. Sin embargo, para la última palabra (!), La RIGHTfunción es la elección incorrecta cuando intenta hacerlo porque desafortunadamente FIND no tiene una bandera para la dirección en la que desea analizar su cadena.

Por lo tanto, toda la cadena simplemente se invierte. LEFTy FINDfunciona normalmente, pero la cadena extraída se invierte. Pero el suyo no es gran cosa una vez que sabe cómo invertir una cadena. La primera ReverseStringdeclaración en la fórmula hace este trabajo.

Ralf
fuente
Eso es mucho más simple que todas las otras opciones aquí, ¡muchas gracias! ¿Por qué Buscar no puede tener un hallazgo inverso, o un sustituto - creo recordar algo que ver con el uso de un número negativo que hacer una búsqueda hacia atrás, pero claramente no VBA ....
Craig Lambie
3
El OP no pidió ningún VBA.
Tripp Kinetics
También eso es una locura! Si va a usar VBA, podría encontrar fácilmente una búsqueda inversa
Denzil Newman,
1
=LEFT(A1,FIND(IF(
 ISERROR(
  FIND("_",A1)
 ),A1,RIGHT(A1,
  LEN(A1)-FIND("~",
   SUBSTITUTE(A1,"_","~",
    LEN(A1)-LEN(SUBSTITUTE(A1,"_",""))
   )
  )
 )
),A1,1)-2)
JB
fuente
1

Copie en una columna, seleccione esa columna y HOME> Edición> Buscar y seleccionar, reemplazar:

Encontrar que:

Replace All.

Hay un espacio después del asterisco.

nueces
fuente
Tenga en cuenta que * es un comodín (codicioso) en las búsquedas de Excel, por lo que coincide con todo hasta el último espacio y lo reemplaza por nada
Superfly Jon
0

Traduje a PT-BR, ya que también necesitaba esto.

(Tenga en cuenta que he cambiado el espacio a \porque solo necesitaba el nombre de archivo de las cadenas de ruta).

=SE(ÉERRO(PROCURAR("\",A1)),A1,DIREITA(A1,NÚM.CARACT(A1)-PROCURAR("|", SUBSTITUIR(A1,"\","|",NÚM.CARACT(A1)-NÚM.CARACT(SUBSTITUIR(A1,"\",""))))))
Marcelo
fuente
3
No sé cómo leer Excel en portugués, así que voy a tener que tomar su palabra para ella :)
e.James
0

Otra forma de lograr esto es la siguiente

=IF(ISERROR(TRIM(MID(TRIM(D14),SEARCH("|",SUBSTITUTE(TRIM(D14)," ","|",LEN(TRIM(D14))-LEN(SUBSTITUTE(TRIM(D14)," ","")))),LEN(TRIM(D14))))),TRIM(D14),TRIM(MID(TRIM(D14),SEARCH("|",SUBSTITUTE(TRIM(D14)," ","|",LEN(TRIM(D14))-LEN(SUBSTITUTE(TRIM(D14)," ","")))),LEN(TRIM(D14)))))

ingrese la descripción de la imagen aquí

Karthick Gunasekaran
fuente
-1

También tuve una tarea como esta y cuando terminé, usando el método anterior, se me ocurrió un nuevo método: ¿Por qué no haces esto?

  1. Invierta la cadena ("cadena uno" se convierte en "eno gnirts").
  2. Use el viejo y bueno Find (que está codificado de izquierda a derecha).
  3. Invierta en cadena legible de nuevo.

¿Como suena esto?

Tod Heartsound
fuente
12
Por supuesto. Pero, ¿cómo invierte la cadena en Excel?
e.James