Home > database >  How to get multiple first matches from regex?
How to get multiple first matches from regex?

Time:12-07

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

Regex demo

Without a lookbehind you can use a capture group:

(?:\s|^)(\.\w (?:[:-] \w )*)[^{}]*\{[^{}]*}

Regex demo

  • Related