Memisahkan teks dari bidang string sebelum setiap pembatas ke bidang baru

9

Saya mencoba untuk mengekstrak data teks dari bidang string yang berisi teks dibatasi oleh titik-titik dan menempatkannya di bidang baru menggunakan kalkulator bidang.

Saya menggunakan fungsi python ini (Diambil dari Cara mengekstrak teks sebelum / di QGIS? ):

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

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

Ini mengembalikan semua teks sebelum titik pertama. Sekarang saya bertanya-tanya bagaimana cara menulis fungsi untuk menempatkan setiap baris teks yang dibatasi di bidang yang terpisah.

Sebelum:

Tabel

Setelah:

Tabel

JWes
sumber

Jawaban:

10

EDIT : Saya mengedit jawaban menurut beberapa komentar oleh JWes .


Anda dapat menjalankan skrip sederhana dari Konsol Python . Pertama, buka Python Console dari Plugins> Python Consoledan aktifkan tombol untuk Editor:

masukkan deskripsi gambar di sini

Kemudian, muat objek (vektor, tabel, dll.) Tempat data Anda disimpan.

Setelah Anda melakukan ini, salin kode berikut di 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()

dan kemudian jalankan:

masukkan deskripsi gambar di sini

Anda akan mendapatkan ini:

masukkan deskripsi gambar di sini

Jika Anda mau, Anda dapat menggunakan kode di atas sebagai fungsi Python untuk kalkulator bidang (saya melihat bahwa Anda sudah tahu cara melakukannya).

mgri
sumber
Saya mendapatkan pesan kesalahan: execfile (u'c: /users/jonwes ~ 1/appdata/local/temp/tmpt2lphm.py'.encode ('mbcs')) Traceback (panggilan terakhir terakhir): File "<input> ", baris 1, dalam File <module>" c: /users/jonwes ~ 1/appdata/local/temp/tmpt2lphm.py ", baris 6, dalam <module> feat [" Atg2 "] = bidang [2] IndexError : daftar indeks di luar kisaran
JWes
1
Ini terjadi karena Anda mungkin memiliki beberapa string yang berbeda dari sampel yang Anda berikan. Kesalahan berarti bahwa tidak ada nilai yang disimpan di posisi No.2 daftar fields. Apakah saya benar?
mgri
Ya Anda benar, pada dasarnya beberapa fitur memiliki lebih banyak informasi yang dibatasi oleh lebih banyak titik daripada fitur lainnya.
JWes
1
Jika Anda dapat memberikan file sampel minimum (di mana saya dapat melihat bagaimana data Anda terstruktur), saya harus dapat menyesuaikan kode dengan kasing Anda. Jika tidak, Anda harus kembali menggunakan persyaratan sendiri karena ada terlalu banyak kemungkinan untuk dikelola tanpa panduan.
mgri
Saya akan memperbarui pertanyaan awal dengan lebih detail tentang struktur data!
JWes
6

Ini bukan metode yang sangat efisien tetapi yang saya gunakan sebelumnya. Pastikan Field2dan Field3ada kemudian gunakan sesuatu seperti berikut:

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

Contoh :

  1. Berikut ini adalah atribut:

    Tabel atribut

  2. Kemudian setelah skrip Anda disimpan, pilih untuk memperbarui Field1dan menggunakan ekspresi:

    func("Field1")

    Editor fungsi

  3. Hasil:

    Hasil

Yusuf
sumber
1
Kami punya ide yang sama! =)
mgri
1
@HowToInQGIS - Memang walaupun saya lebih suka metode Anda karena jauh lebih mudah :)
Joseph