Grupos de cosas iguales, separados por ficha específica

Así que esto es lo que intento hacer, aunque he estado luchando con eso por algún tiempo.

Digamos que tenemos esta entrada:

{{something|a}} text text {{another|one|with|more|items}}

Lo que intento lograr:

[
    ["something", "a"],
    ["another", "one", "with", "more", "items"]
]

La manera simple sería algo como:

"{{something|a}} text text {{another|one|with|more|items}}".scan(/([^\|\{\}]+)/)

Pero esto produce - bastante previsiblemente así - todos los resultados en un único array (también nota que yo no quieres "text text text" en los resultados, sólo los elementos EN los frenos curly:

[["something"], ["a"], [" text text "], ["another"], ["one"], ["with"], ["more"], ["items"]] 

Entonces intenté hacerlo como...ver script aquí):

\{\{(([^\|\{\}]+)\|?)+\}\}

Pero debo estar haciendo algo malo.

Cualquier ayuda será apreciada! :)

Pregunta hecha hace 3 años, 5 meses, 0 días - Por algorithmwizard


3 Respuestas:

  • No puedes conseguir todos los valores capturados de un repetido grupo de captura en Ruby. Siempre hay tantas capturas como los grupos de captura en el patrón.

    Por lo tanto, usted necesita lanzar un poco más de código para obtener la salida esperada:

    s = '{{something|a}} text text {{another|one|with|more|items}}'
    p s.scan(/{{(.*?)}}/).flatten.map{ |x| x.split("|") }
    # => [["something", "a"], ["another", "one", "with", "more", "items"]]
    

    Ver el Ruby demo.

    Note el {{(.*?)}} patrón coincide con un {{ subestring, entonces cualquier cero o más chars aparte de la línea rompe chars tan pocos como sea posible y luego }}Entonces .flatten convierte el resultado en un array de cadena, y luego x.split("|") dentro de un map llamada divide los valores del grupo encontrado capturando con |.

    NOTA: si puede haber rupturas de línea entre {{ y }}, añadir /m modificador, /{{(.*?)}}/m. O, desenrollar el patrón para una mejor eficiencia: /{{[^}]*(?:}(?!})[^}]*)*}}/ (ver Rubular demo).

    Respondida el Dec 17, 2020 a las 09:13 - por compilerczar

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a que estás utilizando un solo grupo de captura en tu expresión regular, por lo que solo captura la última coincidencia de cada grupo entre los delimitadores de llaves. Para lograr el resultado deseado, necesitas usar un grupo de captura dentro de un grupo de repetición en tu expresión regular.

    Aquí hay un ejemplo de cómo puedes modificar tu expresión regular para que funcione correctamente:

    ruby
    string = "{{something|a}} text text {{another|one|with|more|items}}"
    matches = string.scan(/\{\{([^}]+?)\}\}/).map { |match| match[0].split("|") }
    
    p matches
    

    En este código, la expresión regular /\{\{([^}]+?)\}\}/ busca patrones que comienzan con {{, seguido de cualquier cosa que no sea }, y termina con }}. Luego, el método map se utiliza para dividir cada coincidencia basada en el carácter |.

    Al ejecutar este código, obtendrás el siguiente resultado:

    
    [["something", "a"], ["another", "one", "with", "more", "items"]]
    

    Espero que esta solución sea útil para ti. ¡Déjame saber si necesitas más ayuda!

    Respondida el Dec 18, 2020 a las 09:13 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Claro, aquí tienes una posible solución para tu problema:

    
    "{{algo|a}} texto texto |uno|con|mas|elementos}}".scan(/({{.?}\|.?})|(\|.?})/).map do |m|
      m[0] ? m[0][2..-2].split('|') : m[1][1..-1].split('|')
    end
    

    Esta expresión regular busca cadenas entre llaves {{ }} o separadas por tuberías | y las divide en subcadenas. Luego, las subcadenas se asignan a una matriz, donde los elementos entre llaves se encuentran en el primer subarreglo y los elementos separados por tuberías se encuentran en el segundo subarreglo.

    Explicación de la expresión regular:

    ({{.<strong>?}\|.</strong>?}): Busca cadenas entre llaves {{ }} que contengan una o más tuberías |. |: Separa las dos partes de la expresión regular. (\|.<strong>?): Busca elementos separados por tuberías | que contengan uno o más carácteres.

    Ejemplo de uso:

    
    input = "{{algo|a}} texto texto |uno|con|mas|elementos}}"
    output = ["algo", "a", "uno", "con", "mas", "elementos"]
    

    Nota:* Este enfoque asume que no habrá tuberías | dentro de las cadenas entre llaves. Si este es el caso, deberás ajustar la expresión regular en consecuencia.

    Respondida el Dec 18, 2020 a las 09:18 - por Gemini

    Votos positivos: 0 | Votos negativos: 0