Java:有没有更简单的方法来解析字符串中的数组元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1642575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 17:23:49  来源:igfitidea点击:

Java: Is there any simpler way to parse array elements from string?

javastring

提问by Niko Gamulin

In the application there is a string in the following format:

在应用程序中有以下格式的字符串:

String elements = "[11, john,][23, Adam,][88, Angie,]..." (... means there are more elements in the string)

String elements = "[11, john,][23, Adam,][88, Angie,]..." (...表示字符串中有更多元素)

From the given string I have to create an ArrayList for name IDs (11, 23, 88, ...) and ArrayList for names (john, Adam, Angie, ...)

从给定的字符串中,我必须为名称 ID(11、23、88,...)创建一个 ArrayList,为名称(john、Adam、Angie...)创建一个 ArrayList

I created two methods:

我创建了两种方法:

private int getItemID(int listLocation, String inputString){
    int indexBeginning = inputString.indexOf("[", listLocation) + 1;
    int indexEnd = inputString.indexOf(",", listLocation) - 1;
    String sID = inputString.substring(indexBeginning, indexEnd);
    int result = Integer.parseInt(sID);
    return result;
}

private String getItemName(int listLocation, String inputString){
    int indexBeginning = inputString.indexOf(" ", listLocation) + 1;
    int indexEnd = inputString.indexOf(",", indexBeginning) - 1;
    String result = inputString.substring(indexBeginning, indexEnd);
    return result;
}

and intend to use these two methods in the method parseArrayString(String inputString), which I haven't written yet but would work the following way:

并打算在方法 parseArrayString(String inputString) 中使用这两个方法,我还没有编写它,但可以按以下方式工作:

private void parseCommunityList(String inputString){
        int currentLocation = 0;
        int itemsCount = count the number of "[" characters in the string
        for(int i = 0; i < itemsCount; i++)
        {
               currentLocation = get the location of the (i)th character "[" in the string;
               String name = getItemName(currentLocation, inputString);
               int ID = getItemID(currentLocation, inputString);
               nameArray.Add(name);
               idArray,Add(ID);
        }

    }

I would appreciate if anyone of you could suggest any simpler way to create two ArrayLists from the given string.

如果你们中的任何人可以提出任何更简单的方法来从给定的字符串创建两个 ArrayLists,我将不胜感激。

Thanks!

谢谢!

回答by teabot

I would suggest using a regular expression, capturing the elements you want using groups. The example below creates a list of Personobjects instead of individual lists of Strings - encapsulating the data as other posters have suggested:

我建议使用正则表达式,使用组捕获您想要的元素。下面的示例创建了一个Person对象列表,而不是单个Strings列表- 像其他海报建议的那样封装数据:

    List<Person> people = new ArrayList<Person>();

    String regexpStr = "(\[([0-9]+),\s*([0-9a-zA-Z]+),\])";
    String inputData = "[11, john,][23, Adam,][88, Angie,]";

    Pattern regexp = Pattern.compile(regexpStr);
    Matcher matcher = regexp.matcher(inputData);
    while (matcher.find()) {
        MatchResult result = matcher.toMatchResult();

        String id = result.group(2);
        String name = result.group(3);

        Person person = new Person(Long.valueOf(id), name);
        people.add(person);
    }

And a simple class to encapsulate the data:

还有一个简单的类来封装数据:

public class Person {
    private Long id;
    private String name;

    public Person(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    // TODO equals, toString, hashcode...
}

回答by duffymo

Two ArrayLists? I think you need one List containing object type Item with id and name attributes.

两个数组列表?我认为您需要一个包含具有 id 和 name 属性的对象类型 Item 的 List。

If you parse id and name individually, without encapsulating them into an obvious object, you aren't thinking in terms of objects.

如果您单独解析 id 和 name,而不将它们封装到一个明显的对象中,那么您就不是在考虑对象。

回答by Aram Kocharyan

I did something a bit simpler:

我做了一些更简单的事情:

String str = "   [ 1 , 2 ]   ";
str = str.trim();
String[] strArgs = str.substring(1, str.length() - 1).trim().split("\s*,\s*");

回答by toolkit

Something like:

就像是:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IdNamePairs {

    private List<Integer> ids = new ArrayList<Integer>();
    private List<String> names = new ArrayList<String>();

    public IdNamePairs(String string) {
        Pattern p = Pattern.compile("\[([^\]]+)\]");
        Matcher m = p.matcher(string);
        while (m.find()) {
            String tuple = m.group(1);
            String[] idName = tuple.split(",\s*");
            ids.add(Integer.valueOf(idName[0]));
            names.add(idName[1]);
        }
    }

    public List<Integer> getIds() {
        return Collections.unmodifiableList(ids);
    }

    public List<String> getNames() {
        return Collections.unmodifiableList(names);
    }

    public static void main(String[] args) {
        String str = "[11, john,][23, Adam,][88, Angie,]";
        IdNamePairs idNamePairs = new IdNamePairs(str);
        System.out.println(Arrays.toString(idNamePairs.getIds().toArray()));
        System.out.println(Arrays.toString(idNamePairs.getNames().toArray()));
    }
}

回答by Hyman Leow

Here's a simplified example:

这是一个简化的示例:

List<String> nameArray = new ArrayList<String>();
List<String> idArray = new ArrayList<String>();
String input = "[11, john,][23, Adam,][88, Angie,]";
String[] pairs = input.split("((\]\[)|\[|\])");

for (String pair : pairs) {
    if (pair.length() > 0) {
        String[] elems = pair.split(", *");

        idArray.add(elems[0]);
        nameArray.add(elems[1]);
    }
}

System.out.println("IDs: " + idArray);
System.out.println("Names: " + nameArray);

duffymo is right though, about a better OO design.

duffymo 是对的,关于更好的 OO 设计。

回答by michael.kebe

Test included! ;)

包括测试!;)

    class Entry {
        final int number;
        final String name;
        public Entry(int number, String name) {
            this.number = number;
            this.name = name;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            result = prime * result + number;
            return result;
        }
        @Override
        public String toString() {
            return "Entry [name=" + name + ", number=" + number + "]";
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Entry other = (Entry) obj;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            if (number != other.number)
                return false;
            return true;
        }
    }

    class ElementsSplitter {

        public List<Entry> split(String elements) {
            List<Entry> entries = new ArrayList();
            Pattern p = Pattern.compile("\[(\d+),\s*(\w+),\]");
            Matcher m = p.matcher(elements);
            while (m.find()) {
                entries.add(new Entry(Integer.parseInt(m.group(1)), m.group(2)));
            }
            return entries;
        }

    }

    @Test
    public void testElementsSplitter() throws Exception {
        String elementsString = "[11, john,][23, Adam,][88, Angie,]";
        ElementsSplitter eSplitter = new ElementsSplitter();
        List<Entry> actual = eSplitter.split(elementsString);
        List<Entry> expected = Arrays.asList(
                new Entry(11, "john"),
                new Entry(23, "Adam"),
                new Entry(88, "Angie"));
        assertEquals(3, actual.size());
        assertEquals(expected, actual);
    }