0

I am working on a nodeJS application in JavaScript/TypeScript. I am searching a block of text with a regex, so I have an array of matches. I want a neat way of identifying if these strings are adjacent, except for some possible whitespace.

So my current application is this. I am rendering markdown, and if there are two code blocks, one immediately after the other, I want to render them as a tabbed code block.

for (let codeBlock of codeBlocks) {
    var title = /```\s?(.*?\n)/.exec(codeBlock);
    var code = /```.*([\s\S]*?)```/g.exec(codeBlock)[1];
    //console.log('Code: ' + code);
    //console.log('Title: ' + title[1]);
    result.push(code, title[1]);
    var startPos = content.indexOf(code);
    var containsSomething = new RegExp('/[a-z]+/i');
   //if the string between the end of the last code block and the start of this one contains any content
    if (containsSomething.test(content.substring(startPos, lastEndPos))) {
        result.push('n'); // Not a tabbed codeblock
    } else {
        result.push('y'));  //Is a tabbed codeblock
    }
    lastEndPos = code.length + startPos + title[1].length + 6;
    results.push(result);
    result = [];
}

So in the example input below, I need to discern between the top two code blocks which should be tabbed and the third one which shouldn't be.

``` JavaScript                       //in the code example above, this would be the title
    var something = new somethingelse();     //in the code example above, this would be the code
```
``` CSS
.view {
    display: true;
}
```
Some non-code text...

``` html
<div></div>
```
George Edwards
  • 8,979
  • 20
  • 78
  • 161
  • 2
    [`new RegExp(matches.map(RegExp.escape).join('\\s*'))`](https://github.com/benjamingr/RegExp.escape/blob/master/polyfill.js) you may also be interested in [**mixing up the combinations**](http://stackoverflow.com/questions/5752002/find-all-possible-subset-combos-in-an-array) – Paul S. Aug 04 '16 at 22:53
  • @PaulS. the `matches.map` looks really promising, could you add an example as an answer so I can mark it? – George Edwards Aug 04 '16 at 23:15

2 Answers2

1

Using RegExp.escape (polyfill) you could convert your strings into RegExp-safe versions, then create an expression which would match them with variable whitespace,

let matches = ['foo', 'bar'];
let pattern = matches.map(RegExp.escape).join('\\s*'); // "foo\\s*bar"
let re = new RegExp(pattern); // /foo\s*bar/

Now can apply this to your haystack;

re.test('foo\n\n\nbar'); // true
re.test('foo\nbaz\n\nbar'); // false
Paul S.
  • 64,864
  • 9
  • 122
  • 138
0

regex.exec(str) returns an object that contains an index property which shows you where the match starts in the string.

/(\d{3})/.exec('---333').index

The above returns 3, that's where the match starts.

if you have two matches you can check if they're adjacent if the first match's index+length == the second match's index

var re = /(\d{3})/g;
var str = '---333-123---';
var match1 = re.exec(str);
var match2 = re.exec(str);
(match1.index+match1[1].length) == match2.index;

I think this is applicable, but I'm not sure how your code works. Sorry that it's not following your example, but I think this could be useful for you.

Tim van Osch
  • 483
  • 4
  • 16