Bagaimana cara mengekstrak kumpulan bagian string yang sangat spesifik dari string yang didekodekan QR?

Saya perlu memilih bagian tertentu dari string yang sangat besar (yang diterjemahkan dari kode QR) untuk ditetapkan sebagai teks dalam elemen TextView di Android.

//*these are the parts of the string whose corresponding values I need as a text for my TextViews.*

String uid, name, gname, gender, house, street, ps, po, dist, subdist, state, pin, address, dob;

//*this 'string' object holds the decoded qr string*

String string = "uid="001" name="Akbar Shah" gender="M" yob="1989" gname="Jahangir Shah" co="S/O: Jahangir Shah" house="45/5" street="Huzurey Ala Street" vtc="Alibagh" po="Bagnan" dist="Faridabad" subdist="Alamgarh" state="Andhra" pc="6754674" dob="15/04/89"";

//*this is where I am using substring() to get a specific part of the string value*

uid = string.substring(string.indexOf("uid=")+5, string.indexOf("name=")-2);
name = string.substring(string.indexOf("name=")+6, string.indexOf("gender=")-2);
gname = string.substring(string.indexOf("gname=")+7, string.indexOf("co=")-2);
gender = string.substring(string.indexOf("gender=")+8, string.indexOf("yob=")-2);

house = string.substring(string.indexOf("house=")+7, string.indexOf("street=")-2);
street = string.substring(string.indexOf("street=")+8, string.indexOf("vtc=")-2);
ps = string.substring(string.indexOf("vtc=")+5, string.indexOf("po=")-2);
po = string.substring(string.indexOf("po=")+4, string.indexOf("dist=")-2);
dist = string.substring(string.indexOf("dist=")+6, string.indexOf("subdist=")-2);
subdist = string.substring(string.indexOf("subdist=")+9, string.indexOf("state=")-2);
state = string.substring(string.indexOf("state=")+7, string.indexOf("pc=")-2);
pin = string.substring(string.indexOf("pc=")+4, string.indexOf("dob=")-2);
dob = string.substring(string.indexOf("dob=")+5, string.indexOf("/>")-1);

//*this is where I have concatenated the whole address parts into one*
address = house+", "+street+", \nPS - "+ps+", \nPO - "+po+", \nDistrict - "+dist+", \nSub-Division - "+subdist+", \nState - "+state+", \nPin Code - "+pin;

 TextView tv_uid, tv_name, tv_gName, tv_gender, tv_address, tv_dob;

//*this is where  I then setText those substrings for appropriate TextViews*

                    tv_uid.setText(uid);
                    tv_name.setText(name);
                    tv_gName.setText(gname);
                    tv_gender.setText(gender);
                    tv_address.setText(address);
                    tv_dob.setText(dob);

Cara saya melakukan ini hanya dapat berfungsi jika format string QR yang didekodekan tetap sama, yaitu jika string yang didekode sekarang adalah ini:

String string = "uid="001" name="Akbar Shah" gender="M" yob="1989" gname="Jahangir Shah" co="S/O: Jahangir Shah" house="45/5" street= "Jalan Huzurey Ala" vtc="Alibagh" po="Bagnan" dist="Faridabad" subdist="Alamgarh" state="Andhra" pc="6754674" dob="15/04/89"";

Lalu, cara saya mengekstrak tidak akan berhasil jika stringnya terlihat seperti ini:

String string = "uid = "002" name = "Amar Tripathi" gender = "M" yob = "1990" vtc = "Alibagh" po = "Bagnan" dist = "Faridabad" state = "Andhra" pc = "6754674" dob="15/04/89"";

Atau, seperti ini:

String string = "uid = "003" name = "Anthony Gonzalis" gender = "M" yob = "1985" gname = "Jahangir Shah" house = "45/5" street = "Jalan Huzurey Ala" lm = "Di Balik Toko daging" loc="Galianwalabagh" vtc="Alibagh" dist="Faridabad" state="Andhra" pc="6754674" dob="15/04/89"";

Seperti yang mungkin sudah Anda ketahui, substring() tidak dapat digunakan secara universal untuk semua kasus karena dua nilai string terakhir memiliki beberapa bagian yang hilang. Jadi jika saya menentukan untuk mengekstrak substring tertentu yang diapit di antara gname dan co, kecuali untuk kasus pertama, dalam dua kasus terakhir ia tidak akan dapat menemukan co dan karenanya eksekusi kesalahan pengembalian baris kode. Apakah ada cara yang lebih baik untuk melakukannya?

P.S. Bisakah saya mengekstrak semua bagian string dari dalam " "?

Misalnya. "001" adalah bagian dari string yang saya ingin dapatkan bagian 001 yang ada di dalam tanda kutip ganda.


person Bodhisatwa Chakraborty    schedule 20.04.2017    source sumber


Jawaban (2)


Anda bisa menggunakan regex, misalnya "\w*="([^"]*(?="))". Ini memeriksa hal berikut:

  • \w* mencocokkan karakter kata (seperti huruf dan angka) hingga
  • = '=' tercapai yang hanya cocok dengan karakter '=',
  • [^"]* pertama-tama cocok dengan karakter^'"' (yang mewakili karakter pembuka '"') dan kemudian setiap karakter yang bukan '"' hingga
  • (?=") tercapai yang memeriksa apakah karakter berikutnya adalah karakter '"' (yang mewakili karakter penutup '"')

Gunakan ekspresi reguler ini seperti ini: myString.replace("\w*="([^"]*(?="))", "\1"). Itu akan menggantikan seluruh Name="myName" dengan myName saja.

Semoga ini membantu

person Yato    schedule 21.04.2017
comment
Terima kasih Yato atas wawasannya tentang masalah ini. Tapi saya rasa saya telah menemukan cara lain untuk mengatasi masalah ini, saya telah menggunakan XMLPullParser untuk mengekstrak substring spesifik yang saya perlukan. - person Bodhisatwa Chakraborty; 21.04.2017
comment
Ya, itu mungkin lebih mudah dibaca oleh orang lain (atau diri Anda sendiri di masa depan) daripada menggunakan regex untuk ini. Maukah Anda juga menulis ini sebagai jawaban atas pertanyaan Anda sendiri dan menerimanya sehingga pengguna lain dapat melihat solusi Anda untuk masalah tersebut? :) - person Yato; 24.04.2017

Pertama saya membuat kelas DataAttributes.

DataAttributes.java

public class DataAttributes {
    // declare xml attributes of QR code xml response
    public static final String
            DATA_TAG = "PrintLetterBarcodeData",
            UID_ATTR = "uid",
            NAME_ATTR = "name",
            GENDER_ATTR = "gender",
            GNAME_ATTR = "gname",
            HOUSE_ATTR = "house",
            STREET_ATTR = "street",
            LM_ATTR = "lm",
            LOC_ATTR = "loc",
            VTC_ATTR = "vtc",
            PO_ATTR = "po",
            DIST_ATTR = "dist",
            SUBDIST_ATTR = "subdist",
            STATE_ATTR = "state",
            PC_ATTR = "pc",
            DOB_ATTR = "dob";
}

Setelah kode QR dipindai dan disimpan dalam sebuah string.

Dalam aktivitas Anda di mana Anda ingin menampilkan data yang dipindai, dalam kasus saya ini QRActivity... jadi saya membuat metode dengan argumen tunggal -> (String scanData) di kelas QRActivity di QRActivity.java

Di dalamnya tertulis kode berikut

    Log.d("QR Code",scanData);
    XmlPullParserFactory pullParserFactory;

    try {
        // init the parserfactory
        pullParserFactory = XmlPullParserFactory.newInstance();
        // get the parser
        XmlPullParser parser = pullParserFactory.newPullParser();

        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(new StringReader(scanData));

        // parse the XML
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if(eventType == XmlPullParser.START_DOCUMENT) {
                Log.d("QR Code","Start document");
            } else if(eventType == XmlPullParser.START_TAG && DataAttributes.DATA_TAG.equals(parser.getName())) {
                // extract data from tag
                //uid
                uid = parser.getAttributeValue(null,DataAttributes.UID_ATTR);
                //name
                name = parser.getAttributeValue(null,DataAttributes.NAME_ATTR);
                //gender
                gender = parser.getAttributeValue(null,DataAttributes.GENDER_ATTR);
                // guardian name
                gname = parser.getAttributeValue(null,DataAttributes.GNAME_ATTR);
                // house number
                house = parser.getAttributeValue(null,DataAttributes.HOUSE_ATTR);
                // Street name
                street = parser.getAttributeValue(null,DataAttributes.STREET_ATTR);
                // landmark
                lm = parser.getAttributeValue(null,DataAttributes.LM_ATTR);
                // locality
                loc = parser.getAttributeValue(null,DataAttributes.LOC_ATTR);
                // village town city
                vtc = parser.getAttributeValue(null,DataAttributes.VTC_ATTR);
                // Post Office
                po = parser.getAttributeValue(null,DataAttributes.PO_ATTR);
                // district
                dist = parser.getAttributeValue(null,DataAttributes.DIST_ATTR);
                // sub-division
                subdist = parser.getAttributeValue(null,DataAttributes.SUBDIST_ATTR);
                // state
                state = parser.getAttributeValue(null,DataAttributes.STATE_ATTR);
                // Post Code
                pc = parser.getAttributeValue(null,DataAttributes.PC_ATTR);
                // Date of Birth
                dob = parser.getAttributeValue(null,DataAttributes.DOB_ATTR);


            } else if(eventType == XmlPullParser.END_TAG) {
                Log.d("QR Code","End tag "+parser.getName());

            } else if(eventType == XmlPullParser.TEXT) {
                Log.d("QR Code","Text "+parser.getText());

            }
            // update eventType
            eventType = parser.next();
        }

        // display the data on screen
        String na = "N/A";

            if (uid == null){
                        tv_uid.setText(na);
            }else {
                        tv_uid.setText(uid);
            }

            if (name == null){
                        tv_name.setText(na);
            }else {
                        tv_name.setText(name);
            }

            if (gender == null){
                        tv_gender.setText(na);
            }else {
                        tv_gender.setText(gender);
            }

            if (gname == null){
                tv_gName.setText(na);
            }else {
                tv_gName.setText(gname);
            }

            if (house == null){
                tv_house.setText(na);
            }else {
                tv_house.setText(house);
            }

            if (street == null){
                tv_street.setText(na);
            }else {
                tv_street.setText(street);
            }

            if (lm == null){
                tv_lm.setText(na);
            }else {
                tv_lm.setText(lm);
            }

            if (loc == null){
                tv_loc.setText(na);
            }else {
                tv_loc.setText(loc);
            }

            if (vtc == null){
                tv_vtc.setText(na);
            }else {
                tv_vtc.setText(vtc);
            }

            if (po == null){
                tv_po.setText(na);
            }else {
                tv_po.setText(po);
            }

            if (dist == null){
                tv_dist.setText(na);
            }else {
                tv_dist.setText(dist);
            }

            if (subdist == null){
                tv_subdist.setText(na);
            }else {
                tv_subdist.setText(subdist);
            }

            if (state == null){
                tv_state.setText(na);
            }else {
                tv_state.setText(state);
            }

            if (pc == null){
                tv_pc.setText(na);
            }else {
                tv_pc.setText(pc);
            }

            if (dob == null){
                tv_dob.setText(na);
            }else {
                tv_dob.setText(dob);
            }
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Kode di atas adalah contoh bagaimana saya menggunakan XMLPullParserFactory untuk memecah string menjadi beberapa bagian yang sesuai dan kemudian menampilkannya secara terpisah.

Sekarang Anda menggunakan metode yang sesuai dengan tujuan Anda dalam Aktivitas. Saya baru saja menunjukkan cara saya mengimplementasikan XMLPullParserFactory untuk membagi string.

person Bodhisatwa Chakraborty    schedule 03.05.2017