Регулярное выражение JavaScript соответствует символам внутри кавычек, а не в наборе символов - PullRequest
2 голосов
/ 23 июня 2011

У меня есть строка, которую я хотел бы разделить, используя #, ., [], or {} символов, как в CSS. Желаемая функциональность:

- Вход: "div#foo[bar='value'].baz{text}"
- Выход: ["div", "#foo", "[bar='value'", ".baz", "{text"]

Это достаточно просто, с этим RegEx: input.match(/([#.\[{]|^.*?)[^#.\[{\]}]*/g)

Однако это не игнорирует синтаксические символы внутри кавычек, как мне бы этого тоже хотелось. (например, "div[bar='value.baz']" следует игнорировать .)

Как я могу сделать, чтобы вторая часть моего RegEx (часть [^#.\[{\]}]*) захватывала не только отрицательный набор символов, но также любой символ в кавычках. Другими словами, как я могу внедрить RegEx, (\"|').+?\1 в мой текущий.

Edit: Я понял, что регулярное выражение работает достойно, но не может обрабатывать экранированные кавычки внутри кавычек (например: "stuff here \\" quote "). Если кто-то знает, как это сделать, это будет чрезвычайно полезно:

str.match(/([#.\[{]|^.*?)((['"]).*?\3|[^.#\[\]{\}])*/g);

Ответы [ 3 ]

2 голосов
/ 24 июня 2011
var tokens = myCssString.match(/\/\*[\s\S]*?\*\/|"(?:[^"\\]|\\[\s\S]*)"|'(?:[^'\\]|\\[\s\S])*'|[\{\}:;\(\)\[\]./#]|\s+|[^\s\{\}:;\(\)\[\]./'"#]+/g);

Учитывая вашу строку, она производит

div
#
foo
[
bar=
'value.foo'
]
.
baz
{
text
}

Приведенный выше RegExp свободно основан на лексической грамматике CSS 2.1

2 голосов
/ 24 июня 2011
var str = "div#foo[bar='value.baz'].baz{text}";
str.match(/(^|[\.#[\]{}])(([^'\.#[\]{}]+)('[^']*')?)+/g)
// [ 'div', '#foo', '[bar=\'value.baz\'', '.baz', '{text' ]
0 голосов
/ 23 июня 2011

Во-первых, и я не могу не подчеркнуть это достаточно: вы не должны использовать регулярные выражения для синтаксического анализа CSS, вы должны использовать реальный анализатор, например http://glazman.org/JSCSSP/ или аналогичный - многие создали их, не нужновам нужно заново изобрести колесо.

, который сказал, чтобы решить вашу текущую проблему, сделайте это:

var str = "div#foo[bar='value.foo'].baz{text}";

str.match(/([#.\[{]|^.*?)(?:[^#\[{\]}]*|\.*)/g);

//["div", "#foo", "[bar='value.foo'", ".baz", "{text"]
...