2

I want to slip a text by spaces and special character but I want to keep those character. The text I want to separate is in the CSS format. Take the following example:

.box {
  background: red;
  color: white;
}

I already have that in an array format by line like this

[ " .box { " ]
[ " background: red; " ]
[ " } " ]
[ " color: white; " ]

And I want to split every string by space and these characters ':' and ';'

so I'll en up with something like this:

[".box"] ["{"]
["background"] [":"] ["red"] [";"]
["color"] [":"] ["white"] [";"]
["}"]

I want to take in mind the syntax, here are some possible scenarios:

background: red;          -> ["background"] [":"] ["red"] [";"]
background      : red ;   -> ["background"] [":"] ["red"] [";"]
backg    round : red ;    -> ["backg"] ["round"] [":"] ["red"] [";"]

Thanks in advance!

EDIT

About the duplicate question, I'm looking into the other post answer and it might help in my specific case, nevertheless the problem discussed might be in different other context other than parsing CSS. Please consider that, and thank you for the reference.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
OmarAguinaga
  • 707
  • 1
  • 8
  • 17
  • 1
    though you're not spliting by spaces (you are just trimming them) and you are not spliting by `;` neither as that will result in additional empty strings in all the arrays. – ibrahim mahrir Dec 02 '17 at 22:47
  • @ibrahimmahrir If I just do it by spaces this `background: red; ` will become this `["background:"] ["red;"]` and not this ["background"] [":"] ["red"] [";"] – OmarAguinaga Dec 02 '17 at 22:55
  • 1
    Possible duplicate of [Parsing CSS in JavaScript / jQuery](https://stackoverflow.com/questions/3326494/parsing-css-in-javascript-jquery) – str Dec 02 '17 at 22:59

2 Answers2

2

Maybe something like this

var originalText = `.box {
  background: red;
  color: white;
}`;

var parsed = originalText
              .split(/( |:|;|\n)/g) // split and maintain by using capturing group
              .filter(p=>p.trim()); // keep only non whitespace elements

console.log(parsed);
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • Even with this solution there are a lot of selectors that won't be matched. Check this [**Fiddle example** for more details](https://jsfiddle.net/chsdk/Lywqjzs5/) about how it fails. – cнŝdk Dec 04 '17 at 20:59
  • Don't get me wrong here, but all I want to show is that it's a little bit inappropriate to handle all these selectors, we should check for more complex situations. – cнŝdk Dec 04 '17 at 21:02
  • 1
    @chsdk fair enough. I am not trying to pick on you solution, i just have a general aversion to using regex for parsing whole specs. – Gabriele Petrioli Dec 04 '17 at 21:23
1

You can do it with a loop over the array elements and calling .match() with this regex: /(\[\.\#\]?\[a-z\]+\[\s?>+~\s?\[a-z\]+\]?)|(\[{:};\])|(\[a-z0-9\]+)/gi to get all the separate elements:

var results = [];
arr.forEach(function(a) {
  a[0].match(/([\.\#]?[a-z]+[\s?>+~\s?[a-z]+]?)|([{:};])|([a-z0-9]+)/gi).forEach(function(m) {
    results.push(m);
  });
});

You can test the Regex here to see that it matches all CSS selectors.

Demo:

var arr = [
  [" .box { "],
  [" background: red; "],
  [" } "],
  [" color: white; "]
];

var results = [];
arr.forEach(function(a) {
  a[0].match(/([\.\#]?[a-z]+[\s?>+~\s?[a-z]+]?)|([{:};])|([a-z0-9]+)/gi).forEach(function(m) {
    results.push(m);
  });
});
console.log(results);
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • what if no spaces in the property rules? – charlietfl Dec 02 '17 at 22:59
  • This does not work, for example on this `[" background: red; "]` the result should be ["background"] [":"] ["red"] [";"] and instead I get `[ 'background:', 'red;' ]` – OmarAguinaga Dec 02 '17 at 23:00
  • @OmarAguinaga Take a look at my Edit – cнŝdk Dec 02 '17 at 23:10
  • @Downvoter can you please leave a useful comment?! Why would we downvote a correct answer?! – cнŝdk Dec 02 '17 at 23:14
  • 1
    Keep in mind the css rules can be more complicated than the examples given. `#-~+_:` can appear in there. oh and Unicode. – Gabriele Petrioli Dec 03 '17 at 01:03
  • @GabyakaG.Petrioli Yes I know, I updated the regex and it works perfectly with all type of selectors. – cнŝdk Dec 04 '17 at 08:41
  • @OmarAguinaga So does this help you? – cнŝdk Dec 04 '17 at 15:27
  • 1
    Thank you for the answer, I have to say I liked @GabyakaG.Petrioli answer as well, maybe better because is more readable, but since yours solves the specific problem I'll give this to you. – OmarAguinaga Dec 04 '17 at 17:14
  • For regex and css you will really need to see the full specs and create a huge one to handle all cases. Check https://regex101.com/r/doIJVo/2 for failed ones. – Gabriele Petrioli Dec 04 '17 at 20:53
  • @GabyakaG.Petrioli Yes of course, I know that, there are many other selectors and properties that we need to check for. Even your solution, won't work with all kind of selectors. – cнŝdk Dec 04 '17 at 20:57
  • this is totally of topic now but do you have any resources to learn Regex? @chsdk – OmarAguinaga Dec 05 '17 at 01:15
  • @OmarAguinaga First you need to get the concepts of Regular expressions, flags, matches, ... you can take a look at [**Mastering Regular Expressions**](http://shop.oreilly.com/product/9780596528126.do) there are 3 editions of it, then you will be better learning with practice you can check either [**regexr.com**](https://regexr.com/) or [**regex101.com**](https://regex101.com/). This was really helpful in my case. – cнŝdk Dec 05 '17 at 08:14