2

I'm in the process of porting over a Python library to JavaScript / TypeScript. To help myself out, I'm trying to develop various regex rules that I can apply to files that will automatically convert a lot of the syntax and at least get me close, cleaning up where needed.

I've got the following example:

https://regex101.com/r/mIr0pl/1

this.mk(attrs={keyCollection.key: 40}))
this.mk(attrs={keyCollection.key: 50, override.key: override.value})
this.mk(attrs={keyCollection.key: 60, 
               override.key: override.value})

I am trying to do a Find/Replace in my editor, to find all key: value pairs associated with attrs dictionaries. Here's the regex I've got:

/attrs={(.+?):\s*(.+?)}/gms

I want to convert it to this:

this.mk(attrs=[[keyCollection.key, 40]]))
this.mk(attrs=[[keyCollection.key, 50], [override.key, override.value]])
this.mk(attrs=[[keyCollection.key, 60], 
               [override.key, override.value]])

I'm having trouble first nailing down the regex to get the repeated key: value groups, and then also how I would go about utilizing those repeated groups in a replace.

(my editor is VSCode, but I'm using this nifty extension to run these modifications: https://marketplace.visualstudio.com/items?itemName=bhughes339.replacerules)

Any help would be appreciated :)

blitzmann
  • 5,071
  • 4
  • 20
  • 28

2 Answers2

1

Since VS Code already supports infinite-width lookbehind construct you may use

"replacerules.rules": {
    "Wrap the attrs with square brackets first": {
        "find": "(attrs=){([^:{]+:*[^}]*)}",
        "replace": "$1[[$2]]"
    },
    "Format attributes inside attrs": {
        "find": "(?<=attrs=\\[\\[[^\\]]*(?:](?!])[^\\]]*)*),(\\s*)",
        "replace": "],$1["
    },
    "Replace colons with commas inside attrs": {
        "find": "(?<=attrs=\\[\\[[^\\]]*(?:](?!])[^\\]]*)*):",
        "replace": ","
    }
}

"replacerules.rulesets": {
    "Revamp attrs": {
        "rules": [
            "Wrap the attrs with square brackets first",
            "Format attributes inside attrs",
            "Replace colons with commas inside attrs"
        ]
    }
}

Step #1 regex demo

Step #2 regex demo

Step #3 regex demo

Output:

this.mk(attrs=[[keyCollection.key, 40]]))
this.mk(attrs=[[keyCollection.key, 50], [override.key, override.value]])
this.mk(attrs=[[keyCollection.key, 60], 
               [override.key, override.value]])
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
  • This was very informative, exactly what I needed, and includes the config for ReplaceRules too! Thanks so much! – blitzmann Sep 11 '19 at 01:36
0

Maybe,

(?<=attrs={|,)([^:}]*):([^:},]*)(?=}|,)

might be somehow closer.

If you might have had other attrs, you might want to initially filter out those others.


If you wish to explore/simplify/modify the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.


Emma
  • 1
  • 9
  • 28
  • 53