Как извлечь очень специфические наборы частей строки из декодированной строки QR?

Мне нужно было выбрать определенные части очень большой строки (которая декодируется из QR-кода), чтобы установить ее как текст в элементах TextView в 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);

То, как я это сделал, может работать только в том случае, если формат декодированной строки QR остается прежним, т. Е. Если декодированная сейчас строка такова:

String string = "uid="001" name="Акбар Шах" gender="M" yob="1989" gname="Джахангир Шах" co="S/O: Джахангир Шах" house="45/5" street= "Улица Хузурей Ала" vtc="Alibah" po="Bagnan" dist="Faridabad" subdist="Alamgarh" state="Andhra" pc="6754674" dob="15/04/89"";

Тогда мой способ извлечения не сработает, если строка выглядит примерно так:

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

Или вот так:

String string = "uid="003" name="Энтони Гонзалис" gender="M" yob="1985" gname="Джахангир Шах" house="45/5" street="Улица Хузурей Ала" lm="За Мясной магазин" loc="Galianwalabagh" vtc="Alibah" dist="Faridabad" state="Andhra" pc="6754674" dob="15/04/89"";

Как вы, возможно, уже заметили, substring() не может использоваться универсально для всех случаев, потому что в последних двух строковых значениях отсутствуют некоторые части. Поэтому, если я укажу извлекать конкретную подстроку, которая зажата между gname и co, за исключением первого случая, в последних двух случаях он не сможет найти co и, следовательно, выполнение строки кода вернет ошибку. Есть ли лучший способ сделать это?

P.S. Могу ли я просто извлечь все части строки изнутри " "?

Например. «001» — это часть строки, из которой я просто хочу получить часть 001, которая находится внутри двойных кавычек.


person Bodhisatwa Chakraborty    schedule 20.04.2017    source источник


Ответы (2)


вы можете использовать регулярное выражение, например "\w*="([^"]*(?="))". Это проверяет следующее:

  • \w* соответствует символам слова (например, буквам и цифрам) до тех пор, пока
  • = достигается '=', который просто соответствует символу '=',
  • [^"]* сначала соответствует ^'"'-символу (который представляет открывающий '"'-символ), а затем каждому символу, который не является '"', пока
  • (?=") достигается, который проверяет, является ли следующий символ '"'-символом (который представляет собой закрывающий '"'-символ)

Используйте это регулярное выражение так: myString.replace("\w*="([^"]*(?="))", "\1"). Это заменит все Name="myName" просто myName.

Надеюсь это поможет

person Yato    schedule 21.04.2017
comment
Спасибо Ято за понимание этого вопроса. Но я думаю, что нашел другой способ решить эту проблему, я использовал XMLPullParser для извлечения определенных подстрок, необходимых мне. - person Bodhisatwa Chakraborty; 21.04.2017
comment
Да, на самом деле это может быть более удобочитаемым для других (или вас самих в будущем), чем использование для этого регулярного выражения. Не могли бы вы также написать это в ответ на свой вопрос и принять его, чтобы другие пользователи увидели, каково было ваше решение проблемы? :) - person Yato; 24.04.2017

Сначала я создал класс 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";
}

После того, как QR-код сканируется и сохраняется в виде строки.

В вашей деятельности, где вы хотите отображать отсканированные данные, в моем случае это QRActivity... поэтому я создал метод с одним аргументом -> (String scanData) в классе QRActivity в QRActivity.java

Внутри которого написан следующий код

    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();
    }
}

Вышеприведенный код является примером того, как я использовал XMLPullParserFactory для фрагментации строки на соответствующие части, а затем отображал их по отдельности.

Теперь вы используете метод, соответствующий вашей цели в Activity. Я только что показал свой способ реализации XMLPullParserFactory для разделения строки.

person Bodhisatwa Chakraborty    schedule 03.05.2017