Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Распарсить параметры атрибута style (RegExp) (https://javascript.ru/forum/misc/49782-rasparsit-parametry-atributa-style-regexp.html)

BlancoDima 28.08.2014 09:03

Распарсить параметры атрибута style (RegExp)
 
Помогите с регуляркой для сбора параметров атрибута style. Я совершенно не могу понять как нужно делать.
Мне нужно получить все свойства и значения стилей расположенных в style
Вот пример стиля:
[CSS]'background-image: url(http://mysite.ru:8080/img/environment/circle_portret2.jpg); position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial; '[/CSS]

А получить нужно либо массив либо объект, в котором перечислены свойства и их значения.

Я совершенно не знаю регулярки, и единственное до чего я додумался это перечислить свойства и искать до точки с зяпятой =) http://regex101.com/r/hN4kM1/1

Наверняка кто-нибудь делал|сталкивался, но найти готовое решение не получилось к сожалению.
:help:

skrudjmakdak 28.08.2014 09:30

можно и сплитом разбить.. какбэ:
var str = 'background-image: url([url]http://mysite.ru:8080/img/environment/circle_portret2.jpg);[/url] position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial';
var p=str.split(';');
p.forEach(function (val){console.log(val.split(':'));})

BlancoDima 28.08.2014 09:42

Цитата:

Сообщение от skrudjmakdak (Сообщение 327851)
можно и сплитом разбить.. какбэ:
var str = 'background-image: url([url]http://mysite.ru:8080/img/environment/circle_portret2.jpg);[/url] position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial';
var p=str.split(';');
p.forEach(function (val){console.log(val.split(':'));})

Сейчас я как раз сплитом и делаю,

function collectStyle( el ) {
	var result = el.split( "; " );
		for ( var i = 0; i < result.length; i++ ) {
			result[ i ] = result[ i ].split( ": " );
		}
	return result;
}


но там неожиданные : бывают, в url например целых 2 раза. Я что бы лишнее не цеплять спличу с пробелом ': ' и '; ' но это до тех пор пока свойства пишутся с пробелами, а на это расчитывать не приходится

ksa 28.08.2014 09:55

Как вариант...

var css='background-image: url("http://mysite.ru:8080/img/environment/circle_portret2.jpg"); position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial; ';
var re1=/(^|;)([^:]*)/g;
var re2=/(:)([^;]*)/g;
do {
	var prp=re1.exec(css);
	var val=re2.exec(css);
	alert(prp[2]+'='+val[2]);
} while (prp!=null);

ksa 28.08.2014 10:01

Вариант без пробелов...

var css='background-image: url("http://mysite.ru:8080/img/environment/circle_portret2.jpg"); position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial; ';
var re1=/(^|;)(\s*)([^:]*)/g;
var re2=/(:)(\s*)([^;]*)/g;
do {
	var prp=re1.exec(css);
	var val=re2.exec(css);
	alert(prp[3]+'='+val[3]);
} while (prp!=null);

Aetae 28.08.2014 10:39

Имхо такие вещи лучше доверять самому браузеру:
var css = 'background-image: url("http://mysite.ru:8080/img/environment/circle_portret2.jpg"); position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial;';
var style = document.createElement('div').style;
    style.cssText = css;
for(var i = style.length, out = {}; i--;){
  out[style[i]] = style.getPropertyValue(style[i]) + style.getPropertyPriority(style[i]);
}
console.log(out)

Конечно таким образом отсются неверные значения(см. background-repeat), но они и так вряд ли нужны.

BlancoDima 28.08.2014 10:57

ksa Спасибо, может не очень красиво, но вариант рабочий вполне!


Цитата:

Сообщение от Aetae (Сообщение 327862)
Имхо такие вещи лучше доверять самому браузеру:
var css = 'background-image: url("http://mysite.ru:8080/img/environment/circle_portret2.jpg"); position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial;';
var style = document.createElement('div').style;
    style.cssText = css;
for(var i = style.length, out = {}; i--;){
  out[style[i]] = style.getPropertyValue(style[i]) + style.getPropertyPriority(style[i]);
}
console.log(out)

Конечно таким образом отсются неверные значения(см. background-repeat), но они и так вряд ли нужны.

Спасибо, огромное!! Это похоже самый правильный в моём случае вариант, и background* мне в принципе не нужен =) :dance: так что пусть их режет.

alex.vv 28.08.2014 10:58

Парсить CSS свойства до точки с запятой не совсем верно, т.к. у CSS есть шортхенды (shorthands) - сокращенные записи свойств.
То есть например эта запись

margin: 1px 2px 3px 4px;


на самом деле представляет из себя запись сразу 4-х свойств:

margin-top: 1px;
margin-right: 2px;
margin-bottom: 3px;
margin-left: 4px;


Естественно, есть шортхенды и для других свойств (font, background и пр.)

ksa 28.08.2014 11:02

Цитата:

Сообщение от BlancoDima
может не очень красиво

Вот те на... :(

BlancoDima 28.08.2014 11:14

Цитата:

Сообщение от ksa (Сообщение 327867)
Вот те на... :(

Ну в том смысле что не канонично. Но когда это нас останавливало ;)

ksa 28.08.2014 11:19

Цитата:

Сообщение от BlancoDima
Ну в том смысле что не канонично.

Все непонятней и непонятней... :blink:

ixth 28.08.2014 11:24

Может, стоит использовать CSS-парсер?

Aetae 28.08.2014 11:40

Ну если таки писать именно регулярки - я бы сделал как-то так:) :
var css='background-image: url("http://mysite.ru:8080/img/environm;ent:/circle_portret2.jpg"); position: absolute; top: 73px; left: 93px; background-position: 0px 0px; background-repeat: initial initial; ';
var out = {};
css.replace(/(?:^|;)\s*([-a-z]+)\s*:\s*([\s\S]*?)\s*(?=;(?![^(]*\))(?![^{]*\})|$)/gi,function(a,b,c){out[b] = c})
console.log(out)

Выглядит страшно, и не факт что какие-то грабли не упущены.)

ixth, во маньяки.))
Я конечно могу представить для чего он может понадобиться, но всё равно...)

BlancoDima 28.08.2014 12:22

ksa
Цитата:

Сообщение от ksa (Сообщение 327872)
Все непонятней и непонятней... :blink:

Ну в том смысле что не академично :lol:


ixth Не хилая такая библиотечка, слишком сурово для моей задачи.


Aetae
А можно пояснения некоторые? В плане обучения так сказать.
Я понял всё до знака "*?", что это значит, это какое-то особое условие повторения? И это условие зависит от того что идёт в регулярке дальше?
И ещё совсем не понятно для чего вот эта часть "(?![^(]*\))(?![^{]*\})" - типа, если найдёшь эти символы, их не учитывай, или как это перевести на Русский правильно?

Aetae 28.08.2014 12:36

:\s*([\s\S]*?)\s*(?=;(?![^(]*\))(?![^{]*\})|$)
[\s\S]*? - любые символы, до тех пор пока
?=;(?![^(]*\)) - за ними встретится ";" за которой не идёт ")" без предшествующей ей "(". Как-то так.)
Вообще по regexp куча статей(а также моих и не только ответов на этом форуме) - и именно сейчас мне лень в сотый раз расписывать, лучше погуглите.)

P.S. Ещё раз на всякий предупреждаю - вариант наверняка с граблями, и на каком-то случае может загнуться. Я такое обычно использую только при разовой работе для себя.

ksa 28.08.2014 13:03

Цитата:

Сообщение от BlancoDima
Ну в том смысле что не академично

Ясности это так и не дало... :)

BlancoDima 28.08.2014 13:35

Aetae,
Цитата:

и именно сейчас мне лень в сотый раз расписывать
Спасибо, мне этого достаточно, как работает понял.


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