Поиск токенов в строке Java - PullRequest
1 голос
/ 19 июня 2009

Есть ли хороший способ извлечь токены, которые начинаются с заранее определенной строки и заканчиваются заранее определенной строкой?

Например, допустим, начальная строка - «[», а конечная строка - «]». Если у меня есть следующая строка:

"привет [мир] это [[это] меня"

Вывод должен быть:

token [0] = "мир"

token [1] = "[is"

(Примечание: второй токен содержит строку 'start')

Ответы [ 8 ]

8 голосов
/ 19 июня 2009

Я думаю, вы можете использовать функцию Apache Commons Lang , существующую в StringUtils :

substringsBetween(java.lang.String str,
                  java.lang.String open,
                  java.lang.String close)

Документы API говорят это:

Ищет строку для подстрок разграничены начальным и конечным тегом, возвращая все соответствующие подстроки в массив.

Подстроки Commons Lang между API можно найти здесь:

http://commons.apache.org/lang/apidocs/org/apache/commons/lang/StringUtils.html#substringsBetween(java.lang.String,%20java.lang.String,%20java.lang.String)

1 голос
/ 19 июня 2009

Вот способ, которым я бы хотел избежать зависимости от общего языка.

public static String escapeRegexp(String regexp){
    String specChars = "\\$.*+?|()[]{}^";
    String result = regexp;
    for (int i=0;i<specChars.length();i++){
        Character curChar = specChars.charAt(i);
        result = result.replaceAll(
            "\\"+curChar,
            "\\\\" + (i<2?"\\":"") + curChar); // \ and $ must have special treatment
    }
    return result;
}

public static List<String> findGroup(String content, String pattern, int group) {
    Pattern p = Pattern.compile(pattern);
    Matcher m = p.matcher(content);
    List<String> result = new ArrayList<String>();
    while (m.find()) {
        result.add(m.group(group));
    }
    return result;
}


public static List<String> tokenize(String content, String firstToken, String lastToken){
    String regexp = lastToken.length()>1
                    ?escapeRegexp(firstToken) + "(.*?)"+ escapeRegexp(lastToken)
                    :escapeRegexp(firstToken) + "([^"+lastToken+"]*)"+ escapeRegexp(lastToken);
    return findGroup(content, regexp, 1);
}        

Используйте это так:

String content = "hello[world]this[[is]me";
List<String> tokens = tokenize(content,"[","]");
0 голосов
/ 20 июня 2009

Регулярное выражение \\[[\\[\\w]+\\] дает нам [мир] и [[Есть]

0 голосов
/ 19 июня 2009

StringTokenizer не будет сокращать его для указанного поведения. Вам понадобится ваш собственный метод. Что-то вроде:

public List extractTokens(String txt, String str, String end) {
    int                      so=0,eo;
    List                     lst=new ArrayList();

    while(so<txt.length() && (so=txt.indexOf(str,so))!=-1) {
        so+=str.length();
        if(so<txt.length() && (eo=txt.indexOf(end,so))!=-1) {
            lst.add(txt.substring(so,eo);
            so=eo+end.length();
            }
        }
    return lst;
    }
0 голосов
/ 19 июня 2009

Попробуйте регулярное выражение вроде:

(.*?\[(.*?)\])

Второй захват должен содержать всю информацию между множеством []. Однако это не будет работать должным образом, если строка содержит вложенный [].

0 голосов
/ 19 июня 2009

Есть один способ сделать это. Это не особенно красиво. То, что это включает, проходит через строку символ за символом. Когда вы достигаете «[», вы начинаете помещать персонажей в новый токен. Когда вы достигаете «]», вы останавливаетесь. Лучше всего это сделать с использованием структуры данных, а не массива, поскольку массивы имеют статическую длину.

Другое возможное решение - использовать регулярные выражения для метода разбиения String. Единственная проблема, с которой я столкнулся, - это придумать регулярное выражение, которое разделило бы то, что вы хотите. Что я могу придумать, это {] строка символов [) XOR (строка символов [) XOR (] строка символов) Каждый набор скобок обозначает различные регулярные выражения. Вы должны оценить их в этом порядке, чтобы случайно не удалить все, что вы хотите. Я не знаком с регулярными выражениями в Java, поэтому я использовал «строку символов», чтобы обозначить наличие символов в скобках.

0 голосов
/ 19 июня 2009

Обычный строковый токенизатор не будет работать по его требованию, но вы должны настроить его или написать свой собственный.

0 голосов
/ 19 июня 2009

StringTokenizer ? Установите строку поиска на «[]» и флаг «include tokens» на false, и я думаю, что вы установлены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...