Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Регулярное выражение 
:(
    Опции темы
Kizja
Дата 4.10.2007, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



Здрасте, помогите пожалуйста составить регулярное выражение - надо из строки найти все куски, которые находятся между кавычками, составил такое выражение: "\"((.|\\s)*?)\"" - оно находит то, что и требуется, но есть одна бага - если между кавычками нету ни одной буквы, т.е. там или пробелы или перенос строки или числа, но совсем нету букв, то такой кусок брать не надо, а он берёт - помогите пожалуйста исправить!

Пример: "aaa\"bbb\"ccc\" \"dd\nd\"\n\"eee\"x x\nx\""
Сейчас выдаёт:
1. bbb
2.  
3. 

4. x x
x

Неверно 2-ой и 3-ий номер: пустая строка и перенос строки.

Помогите исправить.
PM MAIL   Вверх
Vasay
Дата 4.10.2007, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2097
Регистрация: 8.3.2006

Репутация: 11
Всего: 73



Попробуй так:
\"([^\"]{1,})

Дословно: Любой символ после ", повторяющийся не менее одного раза, кроме ".

Это сообщение отредактировал(а) Vasay - 4.10.2007, 13:44


--------------------
Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны.
PM MAIL   Вверх
Kizja
Дата 4.10.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



Нет, нет - твой вариает не совсем соответствует поставленной задаче - т.е. твой вариает фактически разобьёт строку по кавычкам, начиная с первой встретившейся, т.е. получается такое:
bbb
ccc
 
dd
d


eee
x x
x

Мне же надо найти как бы тот текст, который находится между 2мя кавычками - т.е. первая найденная кавычка начало искомого текста, вторая место конца текста, а в твоём варианте он кавычку конца текста возьмёт опять как начальную.

Вот код который я запускаю для наглядности:

Код

    static String string = "aaa\"bbb\"ccc\" \"dd\nd\"\n\"eee\"x x\nx\"";
    
    public static void blah(String string) {
        Pattern p = Pattern.compile("\"((.|\\s)*?)\"");
//      Pattern p = Pattern.compile("\"([^\"]{1,})");

        Matcher m = p.matcher(string);

        while (m.find()) {
            System.out.println(m.group(1));
        }
    } 

PM MAIL   Вверх
Vasay
Дата 4.10.2007, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2097
Регистрация: 8.3.2006

Репутация: 11
Всего: 73



Тогда вот так: \"([^\"]{1,})\" наверно.


--------------------
Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны.
PM MAIL   Вверх
Kizja
Дата 4.10.2007, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



В таком виде оно работает, если я не ошибаюсь, так же как и мой вариант, приведённый в первом посте: "\"(.*?)\""

Проблема из-за которой я задал вопрос в том, что любые символы не являющиеся буквами допустимы только в сочетании с буквами, но не отдельно, а в таком варианте как у тебя и как у меня он так же берёт и строки состоящие только из пробелов и других вариантов, где нету ни одной буквы:

"abc" - подходит
" a b \n c " - подходит
" " - не подходит
"\n" - не подходит
"123" - не подходит

Любые варианты, где нету букв не подходят.
PM MAIL   Вверх
Vasay
Дата 4.10.2007, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2097
Регистрация: 8.3.2006

Репутация: 11
Всего: 73



Цитата(Kizja @ 4.10.2007,  15:15)
В таком виде оно работает, если я не ошибаюсь, так же как и мой вариант, приведённый в первом посте: "\"(.*?)\""

Проблема из-за которой я задал вопрос в том, что любые символы не являющиеся буквами допустимы только в сочетании с буквами, но не отдельно, а в таком варианте как у тебя и как у меня он так же берёт и строки состоящие только из пробелов и других вариантов, где нету ни одной буквы:

"abc" - подходит
" a b \n c " - подходит
" " - не подходит
"\n" - не подходит
"123" - не подходит

Любые варианты, где нету букв не подходят.

Понял тебя!

Тогда: \"([0-9a-xA-X]{1,})\"
Между кавычками могут быть только от1 до 9, от a до x и от A до X

Хотя в данном случае он не возьмет, скажем такое: " a b \n c " .... сейчас допишу вариант...

Добавлено @ 16:14
Сори, что сразу не понял. Не выспался сегодня  smile 

Попробуй
\"([^"]{0,}[a-xA-X]{1}[^"]{0,})\"  - kregexpeditir обработал все твои примеры правильно

А вобще здесь от задачи зависит

Это сообщение отредактировал(а) Vasay - 4.10.2007, 16:15


--------------------
Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны.
PM MAIL   Вверх
nornad
Дата 4.10.2007, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 16
Всего: 31



Цитата(Kizja @  4.10.2007,  15:14 Найти цитируемый пост)
надо из строки найти все куски, которые находятся между кавычками

Цитата(Kizja @  4.10.2007,  15:14 Найти цитируемый пост)
но есть одна бага - если между кавычками нету ни одной буквы, т.е. там или пробелы или перенос строки или числа, но совсем нету букв, то такой кусок брать не надо

Вполне нормальное поведение. Ты задал сначала задачу получить всё, что находится внутри кавычек. Всё - это всё, включая и пробелы. Так что это не бага. Надо было изначально корректно ставить задачу.

Вот тебе выражение для получения содержимого кавычек только в том случае, если внутри есть есть хотя бы один буквенный символ (латинский, русский или другой алфавит):
Код

\"(.*\p{L}.*])\"


Добавлено через 1 минуту и 35 секунд
Блин, про жадность забыл smile
Код

\"(.*?\p{L}.*?])\"



--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
Kizja
Дата 4.10.2007, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



Спасибо за ответы, теперь вроде как ближе к истине, но баг всё таки есть:

Тестируем с тем же стрингом, что я указывал выше:
Код

static String string = "aaa\"bbb\"ccc\" \"dd\nd\"\n\"eee\"x x\nx\"";


Из всей строки между кавычками находятся: 
1) \"bbb\"  
2) \" \" (пробел)
3) \"\n\" (перенос строки)
4) \"x x\nx\"

Так, из этих четырёх по условию не подходят 2) и 3) потому что нету в них букв.

Запустил с твоим вариантом: \"([^"]{0,}[a-xA-X]{1}[^"]{0,})\"
Получил: 
1) bbb
2)dd\nd
3)eee
Если у тебя получился такой же результат, то бага теперь такая, что он нашёл \"bbb\" - это верно, дальше он доходит до следующего текста между кавычками \" \", т.е. там, где внутри только пробел, его не берёт - что тоже верно, но после этого, на сколько я понял, он начинает рассматривать закрываемые кавычки этой строки с пробелом, как открываемые для следующего и в итоге берёт \"dd\nd\", чего на самом деле делать не должен и дальше уже поскольку сбилась последовательность, то вместо \"x x\nx\" берёт \"eee\". То есть сейчас получается баг в том, что он в какой-то момент путается в закрываемой и открываемой кавычке, после чего всё идёт неправильно дальше. Или может у тебя другой результат выдал?

Добавлено через 12 минут и 25 секунд
nornad, 

Хм, чего-то с этим вариантом \"(.*?\p{L}.*?])\" ничего не выводит вообще - осмелюсь предлопожить, что возможно ты имел в виду такой вариант: \"(.*?\\p{L}.*?)\" т.е. без закрываемой квадратной скобки? - поскольку непонятно почему она там появилась, если открываемой нету, хотя может я просто не осознал всех тонкостей твоей задумки... но если я всё таки прав то 
Код

Pattern p = Pattern.compile("\"(.*?\\p{L}.*?)\"");

выдаёт следующий результат:
bbb
eee
что почти верно, только вместо еее должно бы быть x x\nx
PM MAIL   Вверх
nornad
Дата 4.10.2007, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 16
Всего: 31



Цитата(Kizja @  4.10.2007,  20:32 Найти цитируемый пост)
осмелюсь предлопожить, что возможно ты имел в виду такой вариант

Ага, без скобки и с эскейпингом тоже забыл разобраться. smile
Скобка там повилась потмоу что сначала через символьный класс думал сделать.
Цитата(Kizja @  4.10.2007,  20:32 Найти цитируемый пост)
что почти верно, только вместо еее должно бы быть x x\nx 

А это, извините, из-за жадности. Можно обратно вернуть жадность (вопросики убрать), но тоже не факт, что в этом случае оно отработает верно.
В принципе, твоя задача чисто регулярками может и не решаться - слишком умное определение того, что надо, а что не надо. Если у тебя в строке только одна подстрока с кавычками, то можно сделать, если несколько - не факт.


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
Kizja
Дата 4.10.2007, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



Цитата

В принципе, твоя задача чисто регулярками может и не решаться


Ясно, спасибо за советы, тогда получается мой изначальный вариант можно сказать не уступает тем, что здесь предлагались и думаю, что его тогда вынужден буду и оставить...придётся выковыривать пустышки тогда уже отдельно, чего вобщем-то очень не хотелось. Хотя Vasay сказал, что у него сработало всё верно с его вариантом, хотя я такого результата почему-то тогда не получил.
PM MAIL   Вверх
Vasay
Дата 4.10.2007, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2097
Регистрация: 8.3.2006

Репутация: 11
Всего: 73



to Kizja Прошу прощения за свою вчерашнюю тупость, сказалась бесонная ночь за чтением статей на IBM.com  smile, и как следствие, нулевая внимательность  smile 

Действительно, только регуляркой, здесь, похоже, не обойтись, однако, если
Код

bbb
x x
x

верное решение, могу предложить такой код:
Код

        String string = "aaa\"bbb\"ccc\" \"dd\nd\"\n\"eee\"x x\nx\"";
        Pattern p = Pattern.compile("\"([^\"a-xA-X]{0,}([a-xA-X]{0,})[^\"]{0,})\"",(Pattern.CASE_INSENSITIVE & Pattern.MULTILINE));
        Matcher m = p.matcher(string);
        while (m.find()) {
            if((m.group(2)!=null)&&(!m.group(2).equals("")))
                System.out.println(m.group(1));
        }


Это сообщение отредактировал(а) Vasay - 5.10.2007, 00:02


--------------------
Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны.
PM MAIL   Вверх
Kizja
Дата 6.10.2007, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



Vasay, твой последний вариант думаю самый нормальный, на нём и остановлюсь - только немного переделал и получилось такое:
Код

Pattern p = Pattern.compile("\"([^\"\\p{L}]*([\\p{L}]*)[^\"]*)\"");


Например в твоём варианте непонятно зачем использовать такой вариант: {0,}, если это значит от нуля до бесконечности, что можно представить просто как * и второе неясно почему ты пишешь a-xA-X - алфавит ведь заканчивается на Z, а не на X  smile. И вобщем-то вместо этого взял предложенный nornad вариант про любой буквенный символ: \\p{L}

Так что вот такие пироги.
PM MAIL   Вверх
Vasay
Дата 6.10.2007, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2097
Регистрация: 8.3.2006

Репутация: 11
Всего: 73



Насчет "x" - следствие бессонной ночи  smile , а потом копировал не глядя. Остальное привычка.

Это сообщение отредактировал(а) Vasay - 6.10.2007, 01:04


--------------------
Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0550 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.