0

I'm trying to figure out how to match a set of specific classes -

I want to match classes inline AND/OR a (set of) colors only, either on their own or 2 together:

 

<span class="inline"> should match

<span class="green"> should match

<span class="inline green"> should match

<span class="blue inline"> should match

 --

<span class="inline green blue"> should not match (no more than 2 classes)

<span class="green blue"> should not match (two colors - doesn't have inline class)

 

I've got this at the moment but it's not working:

regex /((inline)?(\s|green|blue|red|yellow))/

Any suggestions? Many thanks

5
  • 2
    Is there a reason why you're doing this with regex, anstead of className or getAttribute('class')? Commented Jun 24, 2013 at 12:24
  • @EliasVanOotegem Yes :) Commented Jun 24, 2013 at 12:55
  • would you mind awfuly giving that reason, because you might miss out on the easier, more reliable and more performant option here... Commented Jun 24, 2013 at 12:57
  • @EliasVanOotegem For the purpose of this app, the 'html' being parsed here is actually text and isn't within the DOM to be able to be selected in this way with straight JS. Commented Jun 24, 2013 at 13:06
  • Thought as much, but that wouldn't prevent you from doing this: var tmpDiv = document.createElement('div'); tmpDiv.innerHTML = htmlString; var spans = tmpDiv.getElementsByTagName('span');, by inserting the spans in a temp div, the markup will be parsed... that's a lot easier than cocking about with regex's, and it's more reliable Commented Jun 24, 2013 at 13:19

1 Answer 1

1

How about the following regex?

/^(?:inline|green|blue|red|yellow)(?:\s+(?:inline|green|blue|red|yellow))?$/

It breaks down as follows:

  • ^: Start of the class string
  • (?:): Non-capturing group. Allows you to group things together without creating a capturing group. This makes things faster.
  • inline|green|blue|red|yellow: An enumeration of all your possible values
  • \s+: One or more whitespace characters. Just \s by itself is a bit limiting, I think.
  • (?:\s+(?:inline|green|blue|red|yellow))?: This makes everything after the first class name completely optional.

Edit:

As per nnnnnn's comment, I think my original regex is ill-suited for the job. However, I think that the following regex should be okay:

/^(?:inline(?:\s+(?:green|blue|red|yellow))?)|(?:green|blue|red|yellow(?:\s+inline)?)$/

Obviously, it's a lot more complicated, but that's why it might be best to simply split the className string of the element on \s+, count the number of elements in the resulting array, and then check each on individually.

Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't this allow "inline inline"?
nnnnnn, yes, you're absolutely right. I hadn't thought of that. After reading the original question more carefully, I think I now understand what Tim wants, and while it can be attained with only a regex, it seems like it would be a really long and complicated regex. I think it would be easier to simply split the className property string on \s+, and then check the individual parts. Anyway, I will try to edit the regex in my post accordingly.

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.