Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > регулярные выражения


Автор: redwhite90 29.11.2012, 13:40
почему при попытке распарсить строку с целю получения все пунктуационных знаков таким образом:
Код

all= text.split("[\\w[\\s]]+");


всё хорошо работает Если на первом месте стоит пунктуационный знак, а если нет, то первый элемент массива all становится пустой строй

Автор: LSD 29.11.2012, 14:15
Цитата
The array returned by this method contains each substring of the input sequence that is terminated by another subsequence that matches this pattern or is terminated by the end of the input sequence.

Т.е. изначальная позиция в строке 0, ищется первое вхождение шаблона. Если первый знак не пунктуация, то он начинается с 0. Значит первая строка получается от 0 до 0.

Автор: redwhite90 29.11.2012, 14:24
Есть предложение как можно это исправить?


Цитата(LSD @  29.11.2012,  14:15 Найти цитируемый пост)
Т.е. изначальная позиция в строке 0, ищется первое вхождение шаблона. Если первый знак не пунктуация, то он начинается с 0. Значит первая строка получается от 0 до 0.

Я наверное Вас не так понял. Если пунктуация первый знак- всё классно, если нет - пробел вылезает

Автор: LSD 29.11.2012, 15:14
Код

    public String[] split(CharSequence input, int limit) {
        int index = 0;
        boolean matchLimited = limit > 0;
        ArrayList<String> matchList = new ArrayList<>();
        Matcher m = matcher(input);

        // Add segments before each match found
        while(m.find()) {
            if (!matchLimited || matchList.size() < limit - 1) {
                String match = input.subSequence(index, m.start()).toString();
                matchList.add(match);
                index = m.end();
            } else if (matchList.size() == limit - 1) { // last one
                String match = input.subSequence(index,
                                                 input.length()).toString();
                matchList.add(match);
                index = m.end();
            }
        }
        ...
    }

Видно, что если find() найдет регион который начинается с 0 символа, то input.subSequence(index, m.start()) даст пустую строку.



Цитата(redwhite90 @  29.11.2012,  15:24 Найти цитируемый пост)
Есть предложение как можно это исправить?

В чем проблема написать код, который будет удалять пустую строку вначале (если есть)?

Автор: redwhite90 29.11.2012, 15:16
Согласен, но думается, что это возможно как то сделать через регулярное положение?

Автор: LSD 29.11.2012, 16:51
Цитата(redwhite90 @  29.11.2012,  16:16 Найти цитируемый пост)
Согласен, но думается, что это возможно как то сделать через регулярное положение?

И что должно быть в первом элементе?

Автор: redwhite90 29.11.2012, 21:14
первый элемент - первый знак препинания, встреченный в строке

Автор: Kircul 30.11.2012, 10:59
Не проверял, но должно быть как-то так:
Код

Collection<String> list = new ArrayList<String>(); // or HashSet
for (Matcher m = Pattern.compile("\\p{Punct}").matcher(str); m.find();) {
    list.add(m.group(0));
}

Автор: Pawl 30.11.2012, 11:41
Я хотел предложить еще такой вариант:
Код

import java.util.ArrayList;

public class PunctsFinder {
    public static void main(String[] args) {
        String str = "qe,qeq,.qe?fe!";    
     ArrayList<String> puncts = new ArrayList<>();;
     for (char c : str.toCharArray()) {
         String p = Character.toString(c);
         if (p.matches("[\\p{Punct}]")) {
             puncts.add(p);
         }
     }    
    }
}

Но вариант Kircul мне понравился больше smile 

Автор: LSD 30.11.2012, 11:48
Цитата(redwhite90 @  29.11.2012,  22:14 Найти цитируемый пост)
первый элемент - первый знак препинания, встреченный в строке 

Вопрос что должно быть с точки зрения контакта метода split(), а не твоей задачи.

Автор: baldina 30.11.2012, 12:10
split здесь просто не подходит, т.к. предназначен для другого.

Добавлено @ 12:12
но её можно приспособить: в начало строки добавить знак пунктуации и пробел, а результирующий массив обрабатывать начиная с 1

Автор: LSD 30.11.2012, 12:22
Цитата(baldina @  30.11.2012,  13:10 Найти цитируемый пост)
но его можно приспособить: в строку первым символом добавить знак пунктуации, а результирующий массив обрабатывать начиная с 1

Знак препинания должен быть с пробелом или еще каким из \w\s символом. Хотя это все равно, чесать левой ухо правой ногой.

Автор: baldina 30.11.2012, 12:26
верно, буковку надо.
Цитата(LSD @  30.11.2012,  12:22 Найти цитируемый пост)
это все равно, чесать левой ухо правой ногой. 

ну так split() для этой задачи - оно и есть.
тут либо как понятней - match и все такое, либо покороче - split с извращениями (алгоритмисты бы сказали - с преобразованием экземпляра задачи  smile)

Автор: LSD 30.11.2012, 12:28
Цитата(baldina @  30.11.2012,  13:26 Найти цитируемый пост)
ну так split() для этой задачи - оно и есть.

Есть подозрение, что ТС не устроит ".:;-" одной строкой и захочется получить их по одному.

Автор: baldina 30.11.2012, 13:08
для этого есть нормальное решение от Kircul, хоть и более длинное

Автор: redwhite90 2.12.2012, 00:57
Всем спасибо)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)