Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Мой RegExp для поиска цветов. (https://javascript.ru/forum/project/27763-mojj-regexp-dlya-poiska-cvetov.html)

Раед 24.04.2012 00:24

Мой RegExp для поиска цветов
 
Начинаю изучать регулярные выражения. Вот моё извращение на тему "Найти цвет в строке":
re = /(?:#[a-f0-9]{3})|(?:#[a-f0-9]{6})|(?:red)|(?:orange)|(?:aqua)|(?:gray)|(?:navy)|(?:silver)|(?:black)|(?:green)|(?:olive)|(?:teal)|(?:blue)|(?:lime)|(?:purple)|(?:white)|(?:fuchsia)|(?:maroon)|(?:red)|(?:yellow)|(?:rgba?\((?:\d+,?)+\))/i

Все замечания, добавления и идеи пишите в тему

P.S. Я понимаю, что это, наверное, не кому не нужно, просто хочу понять, можно ли сделать этот рег как-то проще и лучше

devote 24.04.2012 00:41

re = /#[a-f0-9]{3}|#[a-f0-9]{6}|red|aqua|gray|navy|silver|black|green|olive|teal|blue|lime|purple|white|fuchsia|maroon|red|yellow|rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+(?:\s*,\s*[\d.]+\s*)?\)/i

alert( re.test( "red" ) ); // true
alert( re.test( "rgb(255, 234, 123)" ) ); // true
alert( re.test( "rgba(255, 234, 123, 0.1)" ) ); // true
// куча пробелов
alert( re.test( "rgba(           255,              234,               123,             0.1           )" ) ); // true
alert( re.test( "#f0fe34" ) ); // true
alert( re.test( "#fe4" ) ); // true

alert( re.test( "а нету цвета" ) ); // false
alert( re.test( "белый" ) ); // false

Раед 24.04.2012 10:29

devote,
О, спасибо, думал, что | только на 1 символ действует.

9xakep 24.04.2012 16:29

Раед,
не...прелесть или в рег. выражениях, что "или" работает с человеческой логикой, как в паскале: (a=5) or (a=6), а не так как в js, не напишешь же: a==5 || a==6 || a==7

trikadin 24.04.2012 16:40

9xakep, не понял вашего примера. Как это вообще связано?))

Раед 24.04.2012 17:56

Вот ещё рег для поиска всяких едениц типа 1em 2pt
re=/(?:\s|^)\d+(?:px|em|%|mm|cm|pt|pc|ex)(?=\s|$)/gi

Может кто подскажет, как сделать так, чтобы передний пробел в результат не входил

Раед 24.04.2012 17:58

Цитата:

Сообщение от 9xakep
а не так как в js, не напишешь же: a==5 || a==6 || a==7

В смысле, почему не напишешь?

a = 5
alert(a==5 || a==6 || a==7)

trikadin 24.04.2012 18:01

Будь проще.

re=/\b\d*?(?:px|em|%|mm|cm|pt|pc|ex)\b/gi
str= " 1em ";
alert("'" + str.match(re) + "'");


P. S. Кстати, не уверен, что с точки зрения спецификации указание единиц измерения регистронезависимо. Возможно, флаг i нужно убрать.

Раед 24.04.2012 18:19

А можешь пояснить, что значит \b и чем отличается от [\s^$]. (Справочник читал, но не понял). И ещё по поводу \d*?. Разве могут быть единицы измерения без цифр? А вот без самих обозначений (ну px и т.п.) могут. Что я не понимаю?
re=/\b\d*?(?:px|em|%|mm|cm|pt|pc|ex)\b/gi
str= " 1 ";
alert("'" + str.match(re) + "'");

str = ' px'
alert("'" + str.match(re) + "'");//странновато как-то


Цитата:

Сообщение от trikadin
Кстати, не уверен, что с точки зрения спецификации указание единиц измерения регистронезависимо.

Да я тоже не уверен

9xakep 24.04.2012 18:36

Цитата:

Сообщение от trikadin (Сообщение 170968)
9xakep, не понял вашего примера. Как это вообще связано?))

Воспоминания из дества))

devote 24.04.2012 18:42

Цитата:

Сообщение от 9xakep
Воспоминания из дества))

дауж, не такое уж и далекое детство )))

trikadin 24.04.2012 18:46

Товарищ, учи регэкспы правильно! (с)

А если по теме:
Цитата:

Сообщение от Раед
А можешь пояснить, что значит \b и чем отличается от [\s^$].

\b находит границу слов, например пробел. От [\s^$] отличается тем, что не добавляет граничный символ в результат, что нам и нужно.

Цитата:

Сообщение от Раед
И ещё по поводу \d*?. Разве могут быть единицы измерения без цифр?

\d*? - это нежадный поиск нескольких цифр. Но вообще - вы правы, там должен стоять +.

Цитата:

Сообщение от Раед
А вот без самих обозначений (ну px и т.п.) могут.

Не могут. Моя рега их и не ищет.

Окончательный вариант(с плюсиком)

re=/\b\d+(?:px|em|%|mm|cm|pt|pc|ex)\b/gi
str= " 1em 1 em 2cm 1 1px 2empx";
alert("'" + str.match(re) + "'");


Цитата:

Сообщение от 9xakep
Воспоминания из дества))

Там у вас ошибка, а не различия в языках.

Раед 24.04.2012 18:50

Цитата:

Сообщение от trikadin
Не могут.

Да ну. Типа
body{margin:0;padding:0}
это уже не правильно?

devote 24.04.2012 18:53

Цитата:

Сообщение от Раед
Да ну. Типа body{margin:0;padding:0}это уже не правильно?

ну дык добавь ноль:
re=/\b\d+(?:px|em|%|mm|cm|pt|pc|ex)\b|\b0\b/gi
str= " 1em 1 em 2cm 0 10 1px 2empx";
alert("'" + str.match(re) + "'")

trikadin 24.04.2012 18:56

Цитата:

Сообщение от Раед
это уже не правильно?

Это верный css-синтаксис, согласен. А вы ищете единицы измерения в строке. Чувствуете разницу?

В любом случае, если нужно с поддержой такой штуки - то:
re=/\b(?:\d+(?:px|em|%|mm|cm|pt|pc|ex))|0\b/gi
str= " 1em 1 0 0em em 2cm 1 1px 2empx";
alert("'" + str.match(re) + "'");


P. S. devote, опередил)

melky 24.04.2012 19:13

Цитата:

Сообщение от trikadin (Сообщение 171027)
Это верный css-синтаксис, согласен. А вы ищете единицы измерения в строке. Чувствуете разницу?

не надоест все в регу добавлять?
http://www.w3.org/TR/css3-values/

trikadin 24.04.2012 19:16

melky, надоест) А твои варианты?)

Раед 24.04.2012 19:16

Цитата:

Сообщение от trikadin
Это верный css-синтаксис, согласен. А вы ищете единицы измерения в строке. Чувствуете разницу?

Ну если честно, то в строке стилей

Раед 24.04.2012 19:18

Цитата:

Сообщение от melky
не надоест все в регу добавлять?
http://www.w3.org/TR/css3-values/

С английским конечно проблемы, но то что есть всякие там dppx, vmin и т.п. я понял. Вот только вы сами их хоть раз юзали?

trikadin 24.04.2012 19:24

Цитата:

Сообщение от Раед
Ну если честно, то в строке стилей

Просто добавь 0))

melky 24.04.2012 19:59

Цитата:

Сообщение от trikadin (Сообщение 171030)
melky, надоест) А твои варианты?)

есть тут одна идея :)

псевдокод :
var значение = /*2px, 3345PX, 62in, 3%, 5* .. значение, короче/;
if( верное(значение) ){
    результат = рега.exec(значение); 
}

function верное( значение ){
    // проверить посредством HTML (элемент)
}

код :

PS затестите, пожалуйста, в виндовых браузерах. у меня под рукой только FF и CH
function parseValue(){

    var 
        dummy = document.createElement('b'),
        reg = /(\d+)(%|\w*)/;

    parseValue = function(value){
        if(parseValue.isNormal(value)){
            reg.exec(value);
            return { value: RegExp.$1, dimension: RegExp.$2 };
        }
    };

    parseValue.isNormal = function(value){
        if(value === "0") {
            return true; // "чистый" нуль все вертят, как хотят.
        } else {
            // IE FIX : он метает ошибку, если значение неверное.
            try {
                dummy.style.fontSize = value;  
            } catch(e) {
                return false; // если неверное значение, IE породит ошибку (итог: значение неверное)
            }
            return dummy.style.fontSize === value;
        }
    };

    return parseValue.apply(this, arguments);
}

var a="1px 2in 4% 0 0px 0% 65334em СТОЛpx ы%".split(' ');
var i = 0;
var parsed;
while(i in a){  
    parsed = parseValue(a[i]);
    a[i] = a[i++]+" => "+ (parsed?parsed.value+":"+parsed.dimension:'ничего');
}
alert(a.join('\n'));

Раед 24.04.2012 20:07

melky,
Ну в FF вроде нормально работает

melky 24.04.2012 20:09

Цитата:

Сообщение от Раед (Сообщение 171048)
melky,
Ну в FF вроде нормально работает

интересует в первую очередь IE :)

Раед 24.04.2012 20:11

Цитата:

Сообщение от melky
интересует в первую очередь IE

Зашёл через ИЕ7, так он вообще при нажатии на Посмотреть пишет, что необходимый функционал не поддерживается вашим браузером

melky 24.04.2012 20:24

Цитата:

Сообщение от Раед (Сообщение 171050)
Зашёл через ИЕ7, так он вообще при нажатии на Посмотреть пишет, что необходимый функционал не поддерживается вашим браузером

я забыл про array.map в примере. сейчас поправлю.


Часовой пояс GMT +3, время: 10:25.