5

I'd like to pull out the last class from css rules using Regex in javascript.

The regex rule I'm going for is to start searching from the end of the rule e.g. on '.myClass .myOtherClass' and to bring back the first word after the last full stop - so the result there would be '.myOtherClass'

Example css rules I need to match on:

.myClass{color:red;}
.myClass .myOtherClass{color:green;}
#something .somethingElse{color:blue;}
.something #myIdhere{color:purple;}
#myId {color:black}
.myClass1, .myClass2{colour:green}
.myClass span{colour:purple}
.myPseudo:after{}

I can get the rules out on their own without the {} info. So its the regex would be run one each of the rules on their own. e.g. on '.myClass .myOtherClass' on its own. The output from the rules above that I'd like to get is that it's matches like the below:

.myClass
.myOtherClass
.somethingElse
.something
 no match
.myClass2
.myClass
.myPseudo

Can anyone help please?

CoderPi
  • 12,985
  • 4
  • 34
  • 62
leapin_leprechaun
  • 605
  • 1
  • 4
  • 15
  • 2
    Please share what you already have? – giorgio Dec 07 '15 at 09:35
  • I really only have it up to getting the rules out tbh e.g. string.replace(/[A-Za-z0-9 .#-_]*\{/, '').replace(/\}/, '').trim(); After that I have found a few posts on starting from the end of the string e.g. http://stackoverflow.com/questions/2552428/regex-use-start-of-line-end-of-line-signs-or-in-different-context But I'm not really sure at how to pull that together with a character match. My reg-ex is pretty awful tbh! – leapin_leprechaun Dec 07 '15 at 09:42
  • What is the ultimate reason you are trying to do this? –  Dec 07 '15 at 10:54
  • @torazaburo did you downvote everything here? – CoderPi Dec 07 '15 at 10:59
  • Instead of worrying about downvotes (if anyone downvoted anything it was most likely for the reason that any regexp approach to this problem or any other problem involving parsing languages with regexp is fatally flawed, which seems like a good reason to me), why don't you explain what you are trying to accomplish? –  Dec 07 '15 at 11:10
  • @torazaburo you could at least admit that you where down voting every single post here. If you have an improvement or something important to say leave an answer and do not act like a ... – CoderPi Dec 07 '15 at 11:16
  • My comment is that you should parse CSS with a CSS parser. Your should parse HTML with an HTML parser. You should parse XML with an XML parser. And you should parse almost no language with regexp, unless you're a hopeless masochist. –  Dec 07 '15 at 11:18

3 Answers3

1
.*(\.[a-zA-Z0-9]*) 

retrieving the first group gives you what you want for all your test cases.

It works thanks to the greediness of .* which will match as much as possible, leaving the last class to match to the rest of the pattern.

Try it here

Aaron
  • 24,009
  • 2
  • 33
  • 57
1

This RegEx will work for all valid CSS-Class-Names: (Demo here)

(\.-?[_a-zA-Z]+[_a-zA-Z0-9-]*)

Here is the JavaScript to get all css-class-names and also the last one: (Demo here)

var css = ''
var classNames = css.match(/(\.-?[_a-zA-Z]+[_a-zA-Z0-9-]*)/g)
var lastClass = classNames[classNames.length - 1]

The RegEx is partially taken from: https://stackoverflow.com/a/449000/4339170

Community
  • 1
  • 1
CoderPi
  • 12,985
  • 4
  • 34
  • 62
  • Note his will match classes in comments: `/* .commentedOut{} */`. Also this might not be required, maybe we can find a solution for that. – CoderPi Dec 07 '15 at 10:41
  • Actually, it **won't** match, because `a\:b` is valid. Or, the class might be CSS-namespaced with `!`. Just goes to show that you should not parse CSS (or most other languages) with regexp. Use a parser; that's why they exist. –  Dec 07 '15 at 11:07
  • According to http://www.w3.org/TR/CSS21/grammar.html#scanner and identifier in CSS is `-?{nmstart}{nmchar}*` wich is exactly what was requested and provided. Of cause there is a whole bunch of other stuff if you check the link! But that is not the purpose of this question! – CoderPi Dec 07 '15 at 11:20
  • Right, and--if you look closely--`nmchar` has as one option `escape`. So I'm confused--the purpose of the question is not to come up with a regexp which actually works with all valid CSS classnames? –  Dec 07 '15 at 11:25
  • Yes I saw that `escape`, but as noted in http://stackoverflow.com/a/449000/4339170 this regex covers all basic css class names, wich should be enough for 99% of the time. If you want I can not that in my answer. Would it than be OK for you? – CoderPi Dec 07 '15 at 11:31
  • 1
    I will try that one on my boss--"but my code worked 99% of the time!" –  Dec 07 '15 at 11:41
  • You got it wrong. It will work 100% of the time for this use case. His use case is only one of the 99% use cases. But anyway a code that works 99% of the time might be the best solution, the universe is limited. And a lot of things are to be seen in relation to other things. Maybe you should learn to think in more complex and abstract ways. We are no computers. – CoderPi Dec 07 '15 at 11:42
  • I hereby rescind my offer of employment to you. We actually sort of like really want code which you know works all the time. –  Dec 07 '15 at 16:30
0

Is this what you want?

var str  = 'your css';
var hits = str.match(/\.\w+/gm);
var css  = hits.pop(); //hits[hits.length-1];
CoderPi
  • 12,985
  • 4
  • 34
  • 62
SEOZEN
  • 21
  • 3