7

I have a shapefile with attribute values like this:

C834
K9
L523;L553
W2,T48

I want to display only the characters before certain characters, for example ; and , :

C834
K9
L523
W2

How to achieve this with an label expression in QGIS 3.0?

10

You can use regular expressions like this:

 regexp_substr("yourtextfield",'[^;]*')

To match more characters than ; you can just add it to this expression like:

regexp_substr("yourtextfield",'[^;,]*')

which will return all values before ; or , characters.

enter image description here

3
  • Do you know why your expression '[^;]*' did not require a double backslash '\\', i.e. '\\[^;]*'? – Taras Dec 7 '20 at 7:40
  • @Taras I am not an regular-expressions-expert, but as square brackets are used as metacharacters here, they dont need to be escaped. You only would need to escape them, if you would search for the bracket-character [ or ] itself. Also the double backslash used to escape characters seems to be something QGIS specific. – MrXsquared Dec 7 '20 at 10:22
  • Thank you for clarity – Taras Dec 7 '20 at 12:50
4

You can use a comibination of the expressions strpos and left. Left returns the characters of your text from the left up to the value defined. With strpos you can get the position of a certain character in a string ("finding the position of the comma in your text"). Set this -1 and you have the position until which you want your original string to go.

Combining it both for comma and semicolon, the expression looks like this, where "val" is the name of your attribute field:

left (
    left ( 
        "val", 
        ( strpos ( "val", ',') -1 )
    ), 
    ( strpos( "val", ';') -1 )
)

Just for completion, you can also use arrays in QGIS expressions in combination with array_foreach to replace a series of delimeters, without using regular expressions. The following expression removes everything after the delimiters . , ; - _ However, in this case using the expression used by @MrXsquared is more elegant than this more complex expression:

array_to_string (
    array_remove_all ( 
        ( array_foreach 
            ( array ('.',',',';','-','_'), 
            if (   
                strpos (  "text", @element) =0 
                , 'delete',
                left ( 
                    "text", 
                    ( strpos ( "text", @element) - 1)
                )
            ))
        ), 
    'x')
)

enter image description here

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.