Safari не справляется с regexp'ами при проверке e-mail-адресов
Казалось бы, проблема проверки корректности заполнения поля с адресом электронной почты в форме браузера описана в Интернете 100500 раз. В синтаксесе GWT решение может выглядеть так:
Казалось бы, в чем подвох? Да ни в чем, все браузеры, включая допотопный IE6, справляются с этой процедурой успешно. И Safari справляется, но только… в версии для Windows. А вот Safari, входящий в состав iPad, обрабатывает регулярное выражение некорректно и отбраковывает вполне адекватные e-mail'ы. Можно было бы, конечно, выбрать регэксп попроще, благо в Интернете вариантов немеряно, вплоть до
да вот только где гарантия, что простое выражение окажется яблочному браузеру «по зубам»? Ведь в процессе гугления выяснилось, что с проблемой обработки regexp'ов в Safari столкнулся не только я. Так что пришлось излагать валидацию e-mail другими словами:
От опечаток вполне убережет. Но «война браузеров» задолбала
.
private final static String EMAIL_VALIDATION_REGEX = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";
public static boolean validateEmail(String email) {
return email.matches(EMAIL_VALIDATION_REGEX);
} Казалось бы, в чем подвох? Да ни в чем, все браузеры, включая допотопный IE6, справляются с этой процедурой успешно. И Safari справляется, но только… в версии для Windows. А вот Safari, входящий в состав iPad, обрабатывает регулярное выражение некорректно и отбраковывает вполне адекватные e-mail'ы. Можно было бы, конечно, выбрать регэксп попроще, благо в Интернете вариантов немеряно, вплоть до
/\S@\S/.test(email)да вот только где гарантия, что простое выражение окажется яблочному браузеру «по зубам»? Ведь в процессе гугления выяснилось, что с проблемой обработки regexp'ов в Safari столкнулся не только я. Так что пришлось излагать валидацию e-mail другими словами:
public static boolean validateEmail(String email) {
int at = email.indexOf('@');
int dot = email.lastIndexOf('.');
int spc = email.indexOf(' ');
return at > 1 && dot > at && spc < 0;
} От опечаток вполне убережет. Но «война браузеров» задолбала
.
Вывести содержимое веб-ресурса на экран
Понадобилось скачать исходник на Java из Сети, причем в консольном режиме. Решение простое: команда
выведет поток не в файл, а на экран. Только вот вспомогательный аутпут wget'а всё дело портит:
Наверно, у этой утилиты есть ключи, позволяющие подавить ненужный текст, но мне, почему-то, подумалось, что он направлен в поток сообщений об ошибках, т.е. всё на ту же консоль. Предчувствия не обманули:
Юниксвей, фигли.
wget -O - http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/src/Timeout.javaвыведет поток не в файл, а на экран. Только вот вспомогательный аутпут wget'а всё дело портит:
$ wget -O - http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/src/Timeout.java
--2012-05-03 18:54:32-- http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/src/Timeout.java
Resolving docs.oracle.com... 77.109.171.186, 77.109.171.152
Connecting to docs.oracle.com|77.109.171.186|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2514 (2.5K) [text/plain]
Saving to: `STDOUT'
0% [ ] 0 --.-K/s
/*
* "@(#)Timeout.java 1.1 02/11/01 SMI"
*
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
* и т.д.
Наверно, у этой утилиты есть ключи, позволяющие подавить ненужный текст, но мне, почему-то, подумалось, что он направлен в поток сообщений об ошибках, т.е. всё на ту же консоль. Предчувствия не обманули:
$ wget -O - http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/src/Timeout.java 2>/dev/null
/*
* "@(#)Timeout.java 1.1 02/11/01 SMI"
*
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free,
* license to use, modify and redistribute this software in source and
* binary code form, provided that i) this copyright notice and license
Юниксвей, фигли.
- —
- 03 мая 2012, 23:05
- комментировать
Замена пробелов на нижние подчеркивания в именах файлов
for file in *; do echo mv "${file}" "${file// /_}"; doneНе забудьте убрать слово echo, которое предохраняет от реального переименования на период отладки

Или даже так:
for file in "* *"; do mv "${file}" "${file// /_}"; doneОх уж эти пробелы в именах файлов…
Отсюда.
- —
- 25 апреля 2012, 10:27
- комментировать
JavaFX: новое мЫшленье в вопросах обработки событий
Осваиваю JavaFX, которая, между прочим, весьма динамично развивается (даже не заметил, как вышла версия 2.1). По сравнению со Swing и AWT изменено очень многое. Что-то в сторону упрощения и удобства, но кое-что очень непривычно и поначалу вызывает раздражение. Однако стоит понять общую идею, как приходишь к мысли: «А ведь иначе и быть не должно!» Например, важно понять что такое связывание (binding). В прежних версиях GUI от Java принято было, как и в других средах создания визуальных компонентов, идти именно от видимого: щелкнул курсором по текстовому полю — сработало событие FocusGained или FocusLost, которое очевиднейшим образом обрабатываешь, т.е. меняешь состояние полей, вызываешь методы. Разработчики JavaFX рекомендуют идти от обратного: изменилось состояние некого абстрактного объекта (строки, числа, и т.п.) — происходят изменения в пользовательском интерфейсе. Так что FocusListener или FocusHandler, например, искать в JavaFX бесполезно. Вместо этого делается так:
Т.е. некое свойство GUI-элемента — focusedProperty — изменяется и это влечет за собой события. Как производятся сами изменения — это уж забота системы. Программист же должен сосредоточиться на реакции.
Потихоньку вхожу во вкус такого программирования, которое, хотя и непривычно, но и впрямь очень способствует сосредоточению на бизнес-логике, а не рисовании красивых интерфейсов. Впрочем, интерфейсы и без того получаются довольно симпатичные.
package ru.yababay;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
/**
*
* @author yababay
*/
public class Sample implements Initializable {
@FXML
private TextField label;
@Override
public void initialize(URL url, ResourceBundle rb) {
label.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if(!newValue.booleanValue())
System.out.println(label.getText());
}
} );
}
}Т.е. некое свойство GUI-элемента — focusedProperty — изменяется и это влечет за собой события. Как производятся сами изменения — это уж забота системы. Программист же должен сосредоточиться на реакции.
Потихоньку вхожу во вкус такого программирования, которое, хотя и непривычно, но и впрямь очень способствует сосредоточению на бизнес-логике, а не рисовании красивых интерфейсов. Впрочем, интерфейсы и без того получаются довольно симпатичные.
- —
- 18 апреля 2012, 22:58
- комментировать
Сумма прописью: по-русски и на Java
Потребовалось преобразовать в программе на Java денежные величины, выраженные десятичным письмом, в русские слова, причем в соответствии с бухгалтерскими правилами. Подумал, что поиск готового решения и его адаптация к моему проекту займет примерно столько же времени, сколько и самостоятельная реализация. Да и сама задача показалась интересной, захотелось сделать что-нибудь быстрое и законченное. В итоге за пару часов родилось вот это (см. под катом). Пока преобразуются числа до миллиона, т.к. суммы в моей программе задействованы небольшие. Дело в том, что при преобразовании большого числа с плавающей точкой в строку может появиться форма записи типа 2.977E2. Парсить ее не захотелось, и без того в этой задаче специфики хватает.
Да, русский язык, все-таки, плохо подлежит алгоритмизации. Такие вещи, как «одна тысяЧА», но «две тысяЧИ», «пять тысяЧ»; или, скажем «триСТА», но «пятьСОТ»; или «двадЦАТЬ», но «сорок(!)» и «девяноСТО»; или «двЕ тысячи», но «двА миллиона» — со всем этим пришлось изрядно повозиться.
И еще: как, все-таки, хорошо, что в современных версиях Java можно использовать национальные алфавиты без дополнительных телодвижений.
( Читать дальше )
Да, русский язык, все-таки, плохо подлежит алгоритмизации. Такие вещи, как «одна тысяЧА», но «две тысяЧИ», «пять тысяЧ»; или, скажем «триСТА», но «пятьСОТ»; или «двадЦАТЬ», но «сорок(!)» и «девяноСТО»; или «двЕ тысячи», но «двА миллиона» — со всем этим пришлось изрядно повозиться.
И еще: как, все-таки, хорошо, что в современных версиях Java можно использовать национальные алфавиты без дополнительных телодвижений.
( Читать дальше )
Поиск файла в zip-архивах
Задача, вынесенная в заголовок, встречается не редко. Решается так:
$ for f in $(find . -name "*.zip"); do if ( unzip -l $f | grep [file name] &> /dev/null ); then echo $f; fi; done
- —
- 30 марта 2012, 14:17
- комментировать
Бесплатный репозиторий на Github
Когда-то я писал о том, как получить бесплатный git-репозиторий на хостинге sourceforge. Нынче всё больше проектов перебирается на другой сайт — github. Несколько месяцев назад и я туда переехал, да что-то всё не до кодинга было. Сейчас вот опять занимаюсь программированием и потребовалось забрать с github кое-какие файлы. А забрать-то и не получается: забыл как это делается. Для памятки решил написать этот топик.
Во-первых, идентификация на github осуществляется по паре ключей, поэтому их нужно сгенерировать и публичный выгрузить на сайт через веб-форму:

Далее, нужно в файл ~/.ssh/config добавить нечто вроде
Теперь можно работать с репозиторием, например, синхронизируя его на работе и дома:
Подробности здесь.
Во-первых, идентификация на github осуществляется по паре ключей, поэтому их нужно сгенерировать и публичный выгрузить на сайт через веб-форму:

Далее, нужно в файл ~/.ssh/config добавить нечто вроде
Host github.com
HostName github.com
User myname
IdentityFile ~/.ssh/myprivatekeyfilenameТеперь можно работать с репозиторием, например, синхронизируя его на работе и дома:
git clone [email protected]:mabel/3f-lab.gitПодробности здесь.
- —
- 23 марта 2012, 22:28
- комментировать
Как не нужно писать программы
Сегодня открыл для себя сайт, название и адрес которого в приличном обществе и произнести-то неудобно. Там собраны неэффективные, глупые, а иногда и просто абсурдные фрагменты компьютерных программ. На самых разных языках. Вот, например, китайский код на Java:
Для тех, кто не знаком с этим языком программирования поясню, что любой класс наследуется от Object, так что «extends Object» здесь избыточно. Да еще и собственных полей и методов новый класс не содержит. Так что вся эта конструкция практически абсурдна.
Думаю, даже программист начального уровня улыбнется вот на эти строчки (камент «Ну пожааалуйста!» особенно доставляет):
Или вот метод сортировки простых чисел, написанный на bash'e. Это уже не столько «говнокод», сколько свидетельство нестандартного мышления (я когда въехал — искренне поржал). Хотя неумение использовать утилиту sort чести автору не делает:
А вот над этим кусочком программы, я думаю, посмеется даже тот, кто не знаком с синтаксисом 1С.
Польза от этого сайта такая же, как от зеркала: все мы грешим иногда «быстренькими» решениями, на которые потом без слез не взглянешь. Так что поучиться на чужих ошибках очень даже полезно. Жаль только rss-ленты у них нет. Я бы подписался.
class GGPoint extends Object {
}Для тех, кто не знаком с этим языком программирования поясню, что любой класс наследуется от Object, так что «extends Object» здесь избыточно. Да еще и собственных полей и методов новый класс не содержит. Так что вся эта конструкция практически абсурдна.
Думаю, даже программист начального уровня улыбнется вот на эти строчки (камент «Ну пожааалуйста!» особенно доставляет):
try:
ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBA", 0, -1)
except SystemError:
ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1)Или вот метод сортировки простых чисел, написанный на bash'e. Это уже не столько «говнокод», сколько свидетельство нестандартного мышления (я когда въехал — искренне поржал). Хотя неумение использовать утилиту sort чести автору не делает:
#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
waitА вот над этим кусочком программы, я думаю, посмеется даже тот, кто не знаком с синтаксисом 1С.
Польза от этого сайта такая же, как от зеркала: все мы грешим иногда «быстренькими» решениями, на которые потом без слез не взглянешь. Так что поучиться на чужих ошибках очень даже полезно. Жаль только rss-ленты у них нет. Я бы подписался.
Calipso: как это работает
Идя навстречу пожеланиям трудящихся, продолжаю рассказ о CMS Calipso, на этот раз с картинками. Данная система управления контентом привлекла меня прежде всего тем, что позволяет при разработке дизайна ни в чем себе не отказывать. Этого нет во многих популярных CMS, где нужно не столько знать HTML, CSS и JavaScript, сколько уметь собирать странички из готовых «кубиков». Это называется «натянуть дизайн на движок». В Calipco наоборот — движок прикручивается к дизайну.
( Читать дальше )
( Читать дальше )
Программирование на JavaFX под Linux в NetBeans
Как я уже сообщал, программирование на JavaFX под Linux стало реальностью. Поскольку речь идет о пользовательских интерфейсах со сложными визуальными эффектами, консольное написание программ не очень уместно. Лучше задействовать мощную IDE, например NetBeans. Но если под Windows JDK и JavaFX идут в едином дистрибутиве, устанавливаются вместе и дополнительных настроек при создании проекта не требуют, то под Linux нужно кое-что подшаманить вручную. А именно, в NetBeans открываем Сервис -> Платформы Java. В появившемся диалоге нажимаем «Добавить...» и выбираем каталог, где лежит одна из версий JDK. Когда визард отработает, появится еще одно окно с вкладкой JavaFX (конечно, если вы скачали полную версию NetBeans). На этой вкладке указываем путь, куда распакован JavaFX-дистрибутив.

После этого JavaFX-проекты будут собираться по единственному нажатию на кнопку «Запустиь проект» (если, конечно, в коде нет ошибок).

После этого JavaFX-проекты будут собираться по единственному нажатию на кнопку «Запустиь проект» (если, конечно, в коде нет ошибок).
