9

I'm trying to extract text data from a string field containing text delimited by dots and placing it in new fields using the field calculator.

Im using this python function (Taken from How to extract text before a / in QGIS?):

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def func(value1, feature, parent):
    return value1.split('.')[0]

This returns all text before the first dot. Now I'm wondering how to write the function for it to place each delimited text row in a separate field.

Before:

Tables

After:

Tables

10

EDIT: I edited the answer according to some comments by JWes.


You may run a simple script from the Python Console. Firstly, open the Python Console from Plugins > Python Console and activate the button for the Editor:

enter image description here

Then, load the object (a vector, a table, etc.) where your data are stored.

Once you have done this, copy the following code in the Editor:

layer = iface.activeLayer()
fieldindex = layer.fieldNameIndex("Tasks")
layer.startEditing()
for feat in layer.getFeatures():
    if feat[fieldindex]:
        fields = feat[fieldindex].split('.')
        for i in range(1, len(fields)):
            feat[fieldindex + i] = fields[i - 1]
            layer.updateFeature(feat)
    else:
        continue
layer.commitChanges()

and then run it:

enter image description here

You will obtain this:

enter image description here

If you prefer, you may obviously use the above code as a Python function for the field calculator (I saw that you already know how to do it).

  • I get the error message: execfile(u'c:/users/jonwes~1/appdata/local/temp/tmpt2lphm.py'.encode('mbcs')) Traceback (most recent call last): File "<input>", line 1, in <module> File "c:/users/jonwes~1/appdata/local/temp/tmpt2lphm.py", line 6, in <module> feat["Atg2"] = fields[2] IndexError: list index out of range – JWes Jan 5 '17 at 12:14
  • 1
    This happens because you probably have some strings which are different from the sample you have provided. The error means that there isn't a value stored in the position No.2 of the list fields. Am I right? – mgri Jan 5 '17 at 12:21
  • Yes you're right, basically some features have more information delimited by more dots than other features. – JWes Jan 5 '17 at 12:23
  • 1
    If you can provide a minimum sample file (where I can see how your data are structured), I should be able to adapt the code to your case. Otherwise, it should be necessary to recur to conditionals on your own because there are too many possibilities to manage without an guideline. – mgri Jan 5 '17 at 12:28
  • I'll update the original question with more detail on the data structure then! – JWes Jan 5 '17 at 12:29
6

This is not a very efficient method but is one I used before. Make sure Field2 and Field3 exist then use something like the following:

from qgis.core import *
from qgis.gui import *
import re

@qgsfunction(args='auto', group='Custom')
def func(field, feature, parent):
    # Get active layer
    layer = qgis.utils.iface.activeLayer()
    # Get field indices
    idx_2 = layer.fieldNameIndex('Field2')
    idx_3 = layer.fieldNameIndex('Field3')
    # Extract string values
    first_value = [w for w in re.split('\W', field) if w][0]
    second_value = [w for w in re.split('\W', field) if w][1]
    third_value = [w for w in re.split('\W', field) if w][2]    
    # Update values in fields
    layer.changeAttributeValue(feature.id(), idx_2, second_value)
    layer.changeAttributeValue(feature.id(), idx_3, third_value)
    return first_value

Example:

  1. Here is an attribute:

    Attribute table

  2. Then once your script has been saved, select to update Field1 and use the expression:

    func("Field1")
    

    Function editor

  3. Result:

    Result

  • 1
    We had the same idea! =) – mgri Jan 5 '17 at 12:01
  • 1
    @HowToInQGIS - Indeed although I much prefer your method as it is a lot easier :) – Joseph Jan 5 '17 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.