3

I'm sure I'll bang my head against the wall when I read the answer, but I can't figure this one out.

I have a JSON with fake data to populate a db. One property is called "slug" and contains a string that I'd like to "slugify".

So this:

[
  {
    blah: '[...]'
    slug: 'Plem ap at rem',
    bleh: '[...]',
  },
  {
    blah: '[...]'
    slug: 'Etiam vel augue',
    bleh: '[...]',
  },
]

Should become:

[
  {
    blah: '[...]'
    slug: 'Plem-ap-at-rem',
    bleh: '[...]',
  },
  {
    blah: '[...]'
    slug: 'Etiam-vel-augue',
    bleh: '[...]',
  },
]

I wanted to first target the value and hopelessly capture only the spaces:

slug: '(?:[\w]*([\s])*)+'

I've messed a bit with lookarounds but no luck.

PS: I intend to use it in the VSCode's find&replace, but knowing how would I do this in plain JS is welcome too!

4
  • Not possible in VSC but Notepad++ or Sublime Text would be a solution. Like this (?:slug\W+|\G(?!^))\K(\w+) +. See live demo here regex101.com/r/VVBGhW/1 Commented Oct 7, 2018 at 9:13
  • It's a shame that one doesn't work in js :( Commented Oct 16, 2018 at 14:53
  • 1
    In plain JS it would be easy but unfortunately no way in VSC. Commented Oct 16, 2018 at 15:19
  • @revo How'd it be in js then? Commented Oct 20, 2018 at 18:27

2 Answers 2

4

You can use infinite-width lookahead and lookbehind without any constraint beginning with Visual Studio Code v.1.31.0 release.

You may use

Find What:     (?<=slug: '[^']*)\s
Replace With: -

Details

  • (?<=slug: '[^']*) - a location in a string that is immediately preceded with slug:, space, ' and 0+ chars other than '
  • \s - one whitespace.

See a demo screenshot:

enter image description here

Since you asked how this can be done in JavaScript:

const text = `[\n      {\n        blah: '[...]'\n        slug: 'Plem ap at rem',\n        bleh: '[...]',\n      },\n      {\n        blah: '[...]'\n        slug: 'Etiam vel augue',\n        bleh: '[...]',\n      },\n    ]`;
console.log(text.replace(/(?<=slug: '[^']*)\s/gi, '-'))

Or, if you are using Safari or any other JS environment that does not support ECMAScript 2018 standard:

const text = `[\n      {\n        blah: '[...]'\n        slug: 'Plem ap at rem',\n        bleh: '[...]',\n      },\n      {\n        blah: '[...]'\n        slug: 'Etiam vel augue',\n        bleh: '[...]',\n      },\n    ]`;
console.log(text.replace(/(slug:\s*')([^']*)/gi, function(m,x,y) { 
  return x + y.replace(/\s+/g, '-');
}));

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

1 Comment

That's helpful to know. So, at regex101,com, we should select JavaScript to test these expressions.
-2

UPDATE: Look behinds now supported in VSCode, see Wiktor's answer & vscode/issues/68004


Simple, but rather clunky alternative:

(slug: '\S*)\s replace with: $1-

You'll have to spam click the Replace All button a few times until the match count has gone down to 0 since it only matches the first occurrence on each line. Not ideal I know but if you're just doing it once...

1 Comment

This answer is obsolete as lookbehinds work in VSCode.

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.