I'm using regular expressions to extract all class names from a CSS file. The regex works well if there is only one class, for example .test {margin: 0}
, but if there is a set of classes, for example .test.second.third {margin:0}
, I need only the first class als result: .test
.
My current regex gives me .test, .second, .third
. This is fine, but not what I need in this case. Where is the error in my regular expression?
I'm using it with JavaScript:
code = code.match(/(?:[\.]{1})([a-zA-Z_] [\w-_]*)(?:[\s\.\,\{\>#\:]{0})/igm);
Or here as regex101 sheet: https://regex101.com/r/sgjrHt/1
CodePudding user response:
In your pattern:
- This part
(?:[\.]{1})
is the same as writing\.
- Using
\w
also matches_
so you don't have to add them both to a character class like this[\w-_]
- Note that in that format you would have to escape the hyphen or put it at the start or the end of the character class
If a lookbehind assertion is supported:
(?<!\S)\.\w (?:[:-] \w )*(?=[^{}]*\{[^{}]*})
Explanation
(?<!\S)
Assert a whitespace boundary to the left\.\w
Match.
and 1 word chars(?:[:-] \w )*
Optionally repeat matching:
or-
and 1 word chars(?=
Positive lookahead, assert to the right[^{}]*
Match optional chars other than{
and}
\{[^{}]*}
Match{...}
)
Close the lookahead
Without a lookbehind you can use a capture group:
(?:\s|^)(\.\w (?:[:-] \w )*)[^{}]*\{[^{}]*}