1
votes

i have a bunch of strings in code such as: <td style="background-color:#fdfdff">&nbsp;</td> and <td>&nbsp;</td> in one file.

The goal is to replace &nbsp; from first example with 0, while &nbsp; from second example with - (dash)

I'm using VScode regex, but I can't find the way to replace captured groups with specific values, as $1, $2 groups refer to original string groups. This one is just example, how I'm trying to achieve this, but VScode don't ignore grouped regex.

enter image description here

2
Sorry, but what is the rule? And also, since the conditional replacement patterns are not supported, you will have to use two regexps,so we need to know what is different between the two patterns. The style attribute?Wiktor Stribiżew
Thanks for reply. Difference is, that for first one &nbsp; surrounded by td with style attribute, for second without one (just with <td> tag).Demetera
Then use 1) (?<=<td\s+style="[^"]*">)&nbsp(?=</td>) and replace with 0, and 2) <td>&nbsp;</td> to replace with <td>-</td> (no need for a regex).Wiktor Stribiżew
Thanks Wiktor. It worked (yes) The problem was, I've tried to find the way to replace group, but VScode regex working a bit differentlyDemetera

2 Answers

2
votes

You can use

  1. Search for (?<=<td\s+style="[^"]*">)&nbsp;(?=</td>) and replace with 0, and
  2. Search for <td>&nbsp;</td> and replace with <td>-</td>, no need for a regex here.

Note that capturing groups are meant to keep captured substrings.

The first pattern matches

  • (?<=<td\s+style="[^"]*">) - a place in string that is immediately preceded with <td, one or more whitespaces, style=", any zero or more chars other than " and then a >
  • &nbsp; - a literal string
  • (?=</td>) - immediately to the right, there must be </td>.
2
votes

An alternative process is to use a snippet which can do conditional replacements. With this snippet:

    "replaceTDs": {
      "prefix": "tdr",    // whatever prefix you want 
      "body": [
        "${TM_SELECTED_TEXT/(?<=\">)(&nbsp;)|(&nbsp;)/${1:+0}${2:+-}/g}",
      ]
    }

The conditional replacements can be quite simple since you first find and select only the two alternative texts you are interested in. So

find: <td\s*(style="[^"]*"\s*)>&nbsp;</td>|<td>&nbsp;</td> old version

This simpler find will probably work for you:

<td\s*(style="[^"]*")?\s*>&nbsp;</td>

Don't replace, rather Control+Shift+L : selects all your two alternatives. Esc to focus on editor from the find widget.

Then apply your snippet, in this case type tdr+Tab

and all the changes are made. You just have to make the snippet one time and then do a single find.

td replacement demo


This technique scales a little better than running as many find/replaces as you have replacements to do. Even with more conditional replacements it would probably be a simple change to the one snippet to add more replacements.


Also you can simplify this even more if you use a keybinding to trigger your snippet (you don't have to change focus from the find widget - or create the separate snippet). So with no snippet, but this keybinding:

 {
    "key": "alt+w",
    "command": "editor.action.insertSnippet",
    "args": {
      "snippet": "${TM_SELECTED_TEXT/(?<=\">)(&nbsp;)|(&nbsp;)/${1:+0}${2:+-}/g}"  
    },
    "when": "editorHasSelection"
  }

now the same demo:

td replacement keybinding