Here's an example of what I need to find:
{ n="HOLD", t="INTEGER", v=number },
Replace it with:
{ n="HOLD", t="INTEGER", v=double that number },
Thank you.
Related
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 :)
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]])
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.
I have a large file with a list of objects that have an incrementing page # ie
[
{page: 1},
{page: 2},
{page: 3}
]
I can find each instance of page: # with page: (\d) in vscode's ctrl+f finder. How would I replace each of these numbers with # + 1?
It can be done rather easily in vscode using one of emmet's built-in commands:
Emmet: Increment by 1
Use your regex to find all the page: \d+ in your file.
Ctrl-Shift-L to select all those occurrences.
Trigger the Emmet: Increment by 1 command.
Here is a demo:
It's not possible to perform arithmetic with regex. I use LINQPad to execute these small kind of scripts. An example of how I would do it is in the c# program below.
void Main()
{
var basePath = #"C:\";
// Get all files with extension .cs in the directory and all its subdirectories.
foreach (var filePath in Directory.GetFiles(basePath, "*.cs", SearchOption.AllDirectories))
{
// Read the content of the file.
var fileContent = File.ReadAllText(filePath);
// Replace the content by using a named capture group.
// The named capture group allows one to work with only a part of the regex match.
var replacedContent = Regex.Replace(fileContent, #"page: (?<number>[0-9]+)", match => $"page: {int.Parse(match.Groups["number"].Value) + 1}");
// Write the replaced content back to the file.
File.WriteAllText(filePath, replacedContent);
}
}
I also took the liberty of changing your regex to the one below.
page: (?<number>[0-9]+)
page: matches with "page: " literally.
(?<number> is the start of a named capture group called number. We can then use this group during replacement.
[0-9]+ matches a number between 0 and 9 one to infinite times. This is more specific than using \d as \d also matches other number characters.
The + makes it match more than on digit allowing for the number 10 and onwards.
) is the end of a named capture group.
You could do that in Ruby as follows.
FileIn = "in"
FileOut = "out"
File let's construct a sample file (containing 37 characters).
File.write FileIn, "[\n{page: 1},\n{page: 2},\n{page: 33}\n]\n"
#=> 37
We may now read the input file FileIn, convert it and write it to a new file FileOut.
File.write(FileOut, File.read(FileIn).
gsub(/\{page: (\d+)\}/) { "{page: #{$1.next}}" })
Let's look at what's be written.
puts File.read(FileOut)
[
{page: 2},
{page: 3},
{page: 34}
]
I've gulped the entire file, made the changes in memory and spit out the modified file. If the original file were large this could be easily modified to read from and write to the files line-by-line.
Adding another answer as it is significantly different than the other. I wrote an extension Find and Transform which makes it easy to do math in a find in a file.
In this case with this keybinding (in your keybindings.json file):
{
"key": "alt+r", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "page: (\\d)",
"replace": "page: $${ return $1 + 1 }$$",
"isRegex": true
}
[That could also be a setting in your settings.json file if you wish with slightly different syntax of course.]
The $${ return $1 + 1 }$$ represents a javascript operation. Here 1 will be added to capture group 1 from the find regex.
Within the $${ ... }$$ almost any javascript operation can be inserted. There are many examples in the repo.
I need a regular expression to validate a String like this:
1678;1678;1678;1678 and 1;0;1;1;0;1
I tried to use this pattern:
db.getCollection('CollectionName').find(
{
"magnitude": /^[1678][1678]$/,
"flag": /^[1][1]$/
}
)
but it doesnt works, i try this two patterns that works separate but not both at the same time
db.getCollection('CollectionName').find(
{
"magnitude": /[1678]$/,
"flag": /[1]$/
}
)
db.getCollection('CollectionName').find(
{
"magnitude": /^[1678]/,
"flag": /^[1]/
}
)
I didnt find any character like * in SQL to use in this
I am using robomongo 1.0.0 for querys
I will apreciate any help
Thanks in advance
If you want to match more than one ; separated strings then use capturing groups.
db.getCollection('CollectionName').find(
{
"magnitude": /^1678(;1678)*$/,
"flag": /^[01](;[01])*$/
}
)
(;1678)* matches the string ;1678, zero or more times.
[01] matches either 0 OR 1
how could I parse this response text using Regex?
info = {
"title": "Developers",
"image": "http://i.ytimg.com/vi/KMU0tzLwhbE/default.jpg",
"length": "3",
"status": "serving",
"progress_speed": "",
"progress": "",
"ads": "",
"pf": "http://70efd.pf.aclst.com/ping.php/10754233/KMU0tzLwhbE?h=882634",
"h": "87d0670f6822946338a610a6b9ec5322",
"px": ""
};
The outcome I need should look like this "87d0670f6822946338a610a6b9ec5322", however, I can't get the correct syntax. I'm new to using Regex and what I have tried using is "\s+", can anyone point me in the right direction?
If you must use a regex, you could use a regex along the lines of:
"h" : "(.+?)",
You can see an example of it here. Just read from the first capture group and that would select your text.
That looks like like JSON aside from the info = prefix. If you have any specific language you are working in that could parse JSON, that might be a better way of handling that input.
You could also use (?<="h": ")[a-z0-9]+(?="), which will match any sequence of lowercase letters and numbers, as long as the sequence is preceded by "h": " and followed by ". I made an explanation and demonstration here.
I have a big JSON file, formatted over multiple lines. I want to find objects that don't have a given property. The objects are guaranteed not to contain any further nested objects. Say the given property was "bad", then I would want to locate the value of"foo" in the second element in the following (but not in the first element).
{
result: [
{
"foo" : {
"good" : 1,
"bad" : 0
},
"bar" : 123
},
{
"foo" : {
"good" : 1
},
"bar" : 123
}
]
}
I know about multi-line regexes in Vim but I can't get anything that does what I want. Any pointers?
Try the following:
/\v"foo"\_s*:\_s*\{%(%(\_[\t ,]"bad"\_s*:)#!\_.){-}\}
When you need to exclude something, you should look at negative look-aheads or look-behinds (latter is slower and unlike vim Perl/PCRE regular expressions do not support look-behinds except fixed-width (or a number of alternative fixed-width) ones).
JSON is a context free grammar and as such is not regular. Unless you can give a much stricter set of rules to go on, no regex will be able to do what you want.