7 votos

Inserción de texto adicional en un campo de cadena con la calculadora de campos en QGIS

En QGIS 3.18.3, tengo una tabla de atributos GeoPackage que contiene un campo de cadena que llamaré "FIELD_1" . Todos los registros "FIELD_1" adoptan la forma de a_a_a_a_a, donde a = texto alfanumérico de longitud variable.

El único patrón coherente dentro de "FIELD_1" es que siempre hay exactamente cuatro guiones bajos, cada uno separado a ambos lados por el texto alfanumérico.

Necesito insertar texto adicional (que llamaré "b") de longitud fija inmediatamente a la derecha del cuarto guión bajo, de forma que la salida sea a_a_a_a_a_ b a.

He revisado las funciones de cadena en la calculadora de campo, y creo que necesito hacer algo como rpad() pero sólo después del cuarto guión bajo. Si esa es la metodología correcta, ¿cómo identifico el cuarto guión bajo? ¿O existe un método más genérico para insertar cadenas en estos casos?

8voto

Braiam Puntos 120

Puede utilizar una expresión regular

regexp_replace('aaa_bbb_ccc_ddd_eee','_([^_]*)$','*XYZ\\1')

\==> aaa_bbb_ccc_ddd*XYZeee

Vamos a desglosarlo:

_([^_]*)$

_ encontrar un guión bajo
() guardará lo que encuentre dentro del paréntesis como un grupo de captura, que se denominará \\1
[^_] seguido de cualquier carácter que no sea un guión bajo
* repetir varias veces la instrucción anterior (es decir, obtener cualquier carácter que no sea un guión bajo)
$ hasta el final de la cadena

y podemos sustituir este guión bajo seguido de múltiples caracteres no subrayados por lo que se quiera. Tenga en cuenta que el propio guión bajo se elimina (puede volver a escribirlo, cambiar la parte de sustitución por '_XYZ\\1' )

Para que funcione con los datos de la tabla, basta con sustituir la cadena codificada por el nombre de columna deseado

regexp_replace(the_column_name,'_([^_]*)$','*XYZ\\1')

2voto

DArctur Puntos 11

La respuesta de JGH es genial, pero asume que la cadena termina en el carácter que quieres modificar. Si ese es el caso, usted no tiene que buscar en toda la cadena y en su lugar encontrar los caracteres no subraya al final de la cadena:

([^_]*)$

Esto parece ser un error en la función regex_replace de la calculadora de campos ( ver esta pregunta ).

Si necesita buscar sin anclarse a la parte trasera o delantera, podría utilizar una mirada positiva hacia atrás. Así obtendrá el primer carácter que no sea guión bajo después del cuarto guión bajo, que podrá modificar.

(?<=[^_]{1}_{1}[^_]{1}_{1}[^_]{1}_{1}[^_]{1}_{1})([^_]){1}

Para un lookbehind de longitud variable, utilice este patrón (aunque no todos los motores regex admiten lookbehinds/aheads de longitud variable, aunque PostgreSQL sí lo hace):

'(?<=[^_]*_{1}[^_]*_{1}[^_]*_{1}[^_]*_{1})([^_]){1}'

Enlace de prueba de Regex: https://regex101.com/r/6jiHAn/1/

Utilización en el campo Calc:

regexp_replace('a_a_a_a_a','(?<=[^_]{1}_{1}[^_]{1}_{1}[^_]{1}_{1}[^_]{1}_{1})([^_]{1})','c\\1')

Da 'a_a_a_a_ca'

enter image description here

2voto

Mister Smith Puntos 133

Trato de mantenerme alejado de Regex Voodoo si puedo evitarlo. Yo usaría Python en el Editor de Funciones. Mucho más legible en mi opinión.

Introdúzcalo en la pestaña Editor de funciones de la Calculadora de expresiones,

@qgsfunction(args='auto', group='Custom', )  #Necessary for QGIS to recognize the function
def addtext(original_text, insert_text, feature, parent):  
    index = original_text.rfind("_") + 1  #Find the last underscore and add one to the index
    output = original_text[:index] + insert_text + original_text[index:] # insert the text at the index
    return output

A continuación, en la calculadora de expresiones, utilice lo siguiente

addtext(FIELD_1, "textYouWantToAdd")

Encontrará más documentación sobre el Editor de funciones aquí .

2voto

Elliott Maynard Puntos 11

Sólo porque podemos, cómo resolver su pregunta utilizando matrices:

enter image description here

El código:

with_variable('a', string_to_array( 'a_a_a_a_a', '_'),
  with_variable('a_len', array_length(@a), 
    with_variable('last', array_get(@a, @a_len-1), 
      with_variable('sliced', array_remove_at(@a, @a_len-1),
        array_to_string(array_append(@sliced, 'b' + @last), '_')
))))

Pasos:

  1. Construye el array a partir de la cadena original.
  2. Obtén su longitud.
  3. Obtener el último elemento.
  4. Elimina el último elemento.
  5. Añade 'b' al último elemento y añádelo al array cortado.
  6. Convertir a cadena.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X