Forum: Rails-ES Substring

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jose Antonio P. (Guest)
on 2008-12-15 20:00
 Hola lista,

 Se que la peticion que voy a realizar iria mas bien en el apartado de
Ruby, pero si no es mucha molestia...
 Necesito que de un String, me devuelva un substring desde el primer
caracter hasta la primera secuencia de '\n\n'. He estado mirando en la
documentacion de Ruby, pero no encuentro ninguna funcion que me permita
hacer esto.
 Lo podria hacer tratando como un array el string e ir recolectando
todos los caracteres hasta encontrar dos \n seguidos, pero si hubiera
una funcion mas cortita pues mejor.
 ¿Alguien me podria dar una pista? Gracias!
javier ramirez (Guest)
on 2008-12-15 20:14
(Received via mailing list)
hola,

>  Lo podria hacer tratando como un array el string e ir recolectando
> todos los caracteres hasta encontrar dos \n seguidos, pero si hubiera
> una funcion mas cortita pues mejor.
>  ¿Alguien me podria dar una pista? Gracias!
>

hay muchas formas. Ésta es sólo una

tu_cadena.split('\n\n')[0]

según cómo esté la cosa lo mismo necesitas comillas dobles para que te
reconozca el \n

saludos,



--
javier ramírez

..i do ruby on rails development in madrid, spain, at
http://www.aspgems.com
..you can find out more about me on http://formatinternet.wordpress.com
and http://workingwithrails.com/person/5987-javier-ramirez
Rodrigo B. (Guest)
on 2009-01-10 02:39
Puedes usar t@mbien el poder de los grupos en las expresiones regulares
(te recomiendo le dediques un tiempo para aprenderlos a usar ...te
ahorraran varias lineas de codigo)


tu_cadena =~ /(.+)\n\n/
antes_de_los_dos_newlines=$1

el $1 representa lo que se captura dentro del primer parentesis.

-r.
Xavier N. (Guest)
on 2009-01-10 12:57
(Received via mailing list)
2009/1/10 Rodrigo B. <removed_email_address@domain.invalid>:

> Puedes usar t@mbien el poder de los grupos en las expresiones regulares
> (te recomiendo le dediques un tiempo para aprenderlos a usar ...te
> ahorraran varias lineas de codigo)
>
>
> tu_cadena =~ /(.+)\n\n/
> antes_de_los_dos_newlines=$1
>
> el $1 representa lo que se captura dentro del primer parentesis.

Como el punto no hace matching con "\n" necesitamos /m:

   /(.+?)\n\n/m

Piensa en "foo\nbar\n\nbaz", de ahi se quiere "foo\nbar".

Como se quiere la primera ocurrencia necesitamos un modificador "?":

   /(.+?)\n\n/m

Piensa en "foo\n\nbar\n\nbaz", de ahi queremos "foo".

Por otro lado, si fuera posible que "\n\n" se encuentre al principio
usariamos otro cuantificador:

   /(.*?)\n\n/m

En cuyo caso la subcadena podria ser una cadena vacia.
Fernando G. (Guest)
on 2009-01-10 15:23
(Received via mailing list)
El día 10 de enero de 2009 11:57, Xavier N. 
<removed_email_address@domain.invalid>
escribió:>
> Como se quiere la primera ocurrencia necesitamos un modificador "?":
>
>   /(.+?)\n\n/m
>
> Piensa en "foo\n\nbar\n\nbaz", de ahi queremos "foo".

Xavier, me interesa mucho esto de sólo recuperar la primera ocurrencia
y me ha sorprendido mucho esto del operador ? ahí utilizado y la
verdad que funciona:

>> "foo\n\nbar\n\nbaz".match( /(.+)\n\n/m ).to_a
=> ["foo\n\nbar\n\n", "foo\n\nbar"]
>> "foo\n\nbar\n\nbaz".match( /(.+?)\n\n/m ).to_a
=> ["foo\n\n", "foo"]

Yo antes usaba la negación para conseguir esto, que tiene una sintaxis
super liosa y que si el bloque es muy grande genera errores:
>> "foo\n\nbar\n\nbaz".match( /(((?:(?!\n\n).)*).*)\n\n/m ).to_a
=> ["foo\n\nbar\n\n", "foo\n\nbar", "foo"]

Gracias
f.
Xavier N. (Guest)
on 2009-01-10 16:01
(Received via mailing list)
2009/1/10 Fernando G. <removed_email_address@domain.invalid>:

> Xavier, me interesa mucho esto de sólo recuperar la primera ocurrencia
> y me ha sorprendido mucho esto del operador ? ahí utilizado y la
> verdad que funciona:
>
>>> "foo\n\nbar\n\nbaz".match( /(.+)\n\n/m ).to_a
> => ["foo\n\nbar\n\n", "foo\n\nbar"]
>>> "foo\n\nbar\n\nbaz".match( /(.+?)\n\n/m ).to_a
> => ["foo\n\n", "foo"]

Exacto, sucede que los cuantificadores hacen matching hasta tan a la
derecha como se pueda. Por ejemplo toma la cadena "xy":

   .* -> "xy"
   .+ -> "xy"
   .? -> "x"

Ojo que este ultimo es un "?" distinto, es el cuantificador "0 o 1,
pero empieza probando con 1".

A veces nos interesa que el matching suceda tan a la izquierda como se
pueda (esto es, en la primera ocurrencia posible), y ello se indica
añadiendo un "?" al cuantificador:

   .*? -> ""
   .+? -> "x"
   .?? -> ""

Observa las cadenas vacias. Al poner .* dices "0 o más", y al pedir
que sea lo más a la izquierda posible con .*? el matching más a la
izquierda es justamente el del 0. Si hubiera mas regexp y el resto no
hace matching entonces el backtracking en ese punto iria _hacia
adelante_, ya que "x" tambien satisface .*?.

Como .+ es "1 o mas", al poner .+? nos quedamos con "x", que es lo
minimo.
Fernando G. (Guest)
on 2009-01-10 16:40
(Received via mailing list)
El día 10 de enero de 2009 15:00, Xavier N. 
<removed_email_address@domain.invalid>
escribió:>
> A veces nos interesa que el matching suceda tan a la izquierda como se
> hace matching entonces el backtracking en ese punto iria _hacia
> adelante_, ya que "x" tambien satisface .*?.
>
> Como .+ es "1 o mas", al poner .+? nos quedamos con "x", que es lo minimo.

Genial explicado Xavi.. gracias

f.
This topic is locked and can not be replied to.