7

I have a database of motorway junctions which are named like this:

  • M90 J8/A91/B996
  • M90 J1/A90/A921/A985(T)
  • M9 J1A

There is significant variability in the length of the strings but they all follow the same basic pattern of Motorway ID Junction Number / Link Road IDs

How do I extract everything before the first forward slash i.e. the Motorway ID and Junction Number?

I've been trying to use regex_substr based on other answers on here like this: regexp_substr( "NAME", '^(.+)/') but this extracts everything before the last forwardslash. How can I alter it to get the text before the first slash?

7

QGIS' regex engine doesn't support non greedy matches (yet), so it'll always return the longest possible match. Try

regexp_substr( "NAME", '^[^/]+')

That should return all characters from the start of the string which aren't /s.

| improve this answer | |
5

This turns out to be doable without using the regex_substr function. Instead the code

left( "Name", strpos( "Name" ,'/'))`

can be used instead. It works by identifying the string position of the first / and then extracting the text to the left of that position.

If anyone has any suggestions regarding regex_substr I'd still like to see them though.

| improve this answer | |
2

Not sure where in QGIS you want this feature work. If In the field calculator you may define a custom function based on the Python function split().

This image shows the basic definition of such a function. split('/')[0] always returns the text before the first occurrence of '/' or the complete string, if no '/' is found.

split function definition

You can use this new function like this:

usage of split function

| improve this answer | |
0

This happened when I was trying to extract tags in OSM-derived shapefiles. I'd like to extract English names, so I tried the following:

regexp_substr("other_tags",'"name:en"=>"(.+)"')

It returned a huge string after =>", which meant a greedy match.
However when I used the following regular expression:

regexp_substr("other_tags",'"name:en"=>"(.+?)"')

It returned a lazy match.
Later when I was discovering Qt's Documentation (QGIS is based on Qt), I found that the greediness of quantifiers like ? can be inverted, which may be QGIS's case. Although it still needs to be proven by source code, it's still worth noticing that ? in QGIS may function like a "lazy mark".
Therefore, ^(.+?)\/ could be the answer, thanks to Nathan W. (The \/ actually means /, and \ is an escape character. )

| improve this answer | |
  • The answer by Aurus worked for me, using the +? limited the result to the fist word. I needed the first word prior to the first space so used, ^(.+?)\\s – Joel Jun 3 '19 at 22:26
  • For your information, if you want to work other_tags which is an HStore field, it's now natively managed by QGIS 3.4: map_get(htsore_to_map("other_tags"), 'name:en') – etrimaille Jun 4 '19 at 6:08
  • @etrimaille Thank you for a more efficient approach! – Aurus Huang Jun 19 '19 at 0:52

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.