1

I have this line in my loop:

var regex1 = new RegExp('' + myClass + '[:*].*');
var rule1 = string.match(regex1)

Where "string" is a string of class selectors, for example: .hb-border-top:before, .hb-border-left

and "myClass" is a class: .hb-border-top

As I cycle through strings, i need to match strings that have "myClass" in them, including :before and :hover but not including things like hb-border-top2.

My idea for this regex is to match hb-border-top and then :* to match none or more colons and then the rest of the string.

I need to match:

.hb-fill-top::before .hb-fill-top:hover::before .hb-fill-top .hb-fill-top:hover

but the above returns only:

.hb-fill-top::before .hb-fill-top:hover::before .hb-fill-top:hover

and doesn't return .hb-fill-top itself.

So, it has to match .hb-fill-top itself and then anything that follows as long as it starts with :

EDIT:

Picture below: my strings are the contents of {selectorText}. A string is either a single class or a class with a pseudo element, or a rule with few clases in it, divided by commas.

each string that contains .hb-fill-top ONLY or .hb-fill-top: + something (hover, after, etc) has to be selected. Class is gonna be in variable "myClass" hence my issue as I can't be too precise.

enter image description here

0

3 Answers 3

1

I understand you want to get any CSS selector name that contains the value anywhere inside and has EITHER : and 0+ chars up to the end of string OR finish right there.

Then, to get matches for the .hb-fill-top value you need a solution like

/\.hb-fill-top(?::.*)?$/

and the following JS code to make it all work:

var key = ".hb-fill-top";
var rx = RegExp(key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "(?::.*)?$");
var ss = ["something.hb-fill-top::before","something2.hb-fill-top:hover::before","something3.hb-fill-top",".hb-fill-top:hover",".hb-fill-top2:hover",".hb-fill-top-2:hover",".hb-fill-top-bg-br"];
var res = ss.filter(x => rx.test(x));
console.log(res);

Note that .replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') code is necessary to escape the . that is a special regex metacharacter that matches any char but a line break char. See Is there a RegExp.escape function in Javascript?.

The ^ matches the start of a string.

(?::.*)?$ will match:

  • (?::.*)?$ - an optional (due to the last ? quantifier that matches 1 or 0 occurrences of the quantified subpattern) sequence ((?:...)? is a non-capturing group) of a
    • : - a colon
    • .* - any 0+ chars other than line break chars
  • $ - end of the string.
Sign up to request clarification or add additional context in comments.

10 Comments

I will check it when I'm back from work, thanks for the answer. As you can see in the edited question, I have a list of strings that I have to select. String is either 1 (selected) or 0 (skipped) based on this regex. So if the string matches the "key" or "key" with hover, after elements etc, then it will be selected. I'm building a function which basically takes my whole stylesheet, cycles through all the rules and returns only the rules that apply to the class I have put in the "key". It has to return all :hover, :before rules and other chained rules that include "key" in some way.
When you use ^ to mark start of the string here : RegExp("^" + key.replace .... does this not mean that string will only match if it starts with "key" ? Will it work if "key" is somewhere in the middle of the string?
@Varin: The ^ anchors the match at the start of the string. Remove if you do not need that behavior. I edited the JS snippet to filter out the non-matching values.
I downloaded my git repo at work, pasted your regex and it works! It works without the replace string which I don't think I need in this case... also, could you please explain (?::.*)?$ in bit more detail, especially the ?$ part? I'm trying to understand regex more and this would really help! Thanks so much for your help Wiktor!
@Varin I added some more explanations.
|
0

var regex1 = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`)

var passes = [
    '.hb-fill-top::before',
    '.hb-fill-top:hover::before',
    '.hb-fill-top',
    '.hb-fill-top:hover',
    '.hb-fill-top::before',
    '.hb-fill-top:hover::before',
    '.hb-fill-top:hover'
];

var fails = ['.hb-fill-top-bg-br'];

var myClass = '.hb-fill-top';
var regex = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`);

passes.forEach(p => console.log(regex.test(p)));
console.log('---');
fails.forEach(f => console.log(regex.test(f)));

2 Comments

Returns things like .hb-fill-top-bg-br and it should only return hb-fill-top and hb-fill-top:[rest of the string]
Updated. That string now fails and the 7 in your post pass. Can you try again?
0
var regex1 = new RegExp('\\' + myClass + '(?::[^\s]*)?');
var rule1 = string.match(regex1)

This regex select my class, and everething after if it start with : and stop when it meets a whitespace character.

See the regex in action.

Notice also that I added '\\' at the beginning. This is in order to escape the dot in your className. Otherwise it would have matched something else like

ahb-fill-top
.some-other-hb-fill-top

Also be careful about .* it may match something else after (I don't know your set of strings). You might want to be more precise with :{1,2}[\w-()]+ in the last group. So:

var regex1 = new RegExp('\\' + myClass + '(?::{1,2}[\w-()]+)?');

7 Comments

This also returns things like: .hb-fill-top-rev-bg and doesn't select the rest of the string that follows after .hb-fill-top:
Yes it does, see my last edit :) Be sure to detail more your question: for instance add regex that you don't want to match. Then our answers will be more appropriate for sure.
Thanks, but this returns error in the console : Range out of order in character class
Doesn't for me.. I'll need more context if you want I to help you
I edited my question with a picture of a few strings and a further explanation
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.