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.
Related
I'm new to ruby so please excuse my ignorance :)
I just learned about eval and I read about its dark sides.
what I've read so far:
When is eval in Ruby justified?
Is 'eval' supposed to be nasty?
Ruby Eval and the Execution of Ruby Code
so what I have to do is to read a file in which there are some text such as /e/ 3 which will replace each e with a 3 after evaluation.
so here what i did so far:(working but..)
def evaluate_lines
result="elt"
IO.foreach("test.txt") do |reg|
reg=reg.chomp.delete(' ')
puts reg
result=result.gsub(eval(reg[0..2]),"#{reg[3..reg.length]}" )
p result
end
end
contents of the test.txt file
/e/ 3
/l/ 1
/t/ 7
/$/ !
/$/ !!
this only works because I know the length of the lines in the file.
so assuming my file has the following /a-z/ 3 my program would be not able to do what is expected from it.
Note
I tried using Regexp.new reg and this resulted with the following /\/e\/3/ which isn't very helpful in this case.
simple example to the `Regexp
str="/e/3"
result="elt"
result=result.gsub(Regexp.new str)
p result #outputs: #<Enumerator: "elt":gsub(/\/e\/3/)>
i already tried stripping off the slashes but even though this wont deliver the desired result thus the gsub() takes two parameters, such as this gsub(/e/, "3").
for the usage of the Regexp, I have already read Convert a string to regular expression ruby
While you can write something to parse that file, it rapidly gets complicated because you have to parse regular expressions. Consider /\/foo\\/.
There are a number of incomplete solutions. You can split on whitespace, but this will fail on /foo bar/.
re, replace = line.split(/\s+/, 2)
You can use a regex. Here's a first stab.
match = "/3/ 4".match(%r{^/(.*)/\s+(.+)})
This fails on escaped /, we need something more complex.
match = '/3\// 4'.match(%r{\A / ((?:[^/]|\\/)*) / \s+ (.+)}x)
I'm going to guess it was not your teacher's intent to have you parsing regexes. For the purposes of the assignment, splitting on whitespace is probably fine. You should clarify with your teacher.
This is a poor data format. It is non-standard, difficult to parse, and has limitations on the replacement. Even a tab-delimited file would be better.
There's little reason to use a non-standard format these days. The simplest thing is to use a standard data format for the file. YAML or JSON are the most obvious choices. For such simple data, I'd suggest JSON.
[
{ "re": "e", "replace": "3" },
{ "re": "l", "replace": "1" }
]
Parsing the file is trivial, use the built-in JSON library.
require 'json'
specs = JSON.load("test.json")
And then you can use them as a list of hashes.
specs.each do |spec|
# No eval necessary.
re = Regexp.new(spec["re"])
# `gsub!` replaces in place
result.gsub!(re, spec["replace"])
end
The data file is extensible. For example, if later you want to add regex options.
[
{ "re": "e", "replace": "3" },
{ "re": "l", "replace": "1", "options": ['IGNORECASE'] }
]
While the teacher may have specified a poor format, pushing back on bad requirements is good practice for being a developer.
Here's a really simple example that uses vi notation like s/.../.../ and s/.../.../g:
def rsub(text, spec)
_, mode, repl, with, flags = spec.match(%r[\A(.)\/((?:[^/]|\\/)*)/((?:[^/]|\\/)*)/(\w*)\z]).to_a
case (mode)
when 's'
if (flags.include?('g'))
text.gsub(Regexp.new(repl), with)
else
text.sub(Regexp.new(repl), with)
end
end
end
Note the matcher looks for non-slash characters ([^/]) or a literal-slash combination (\\/) and splits out the two parts accordingly.
Where you can get results like this:
rsub('sandwich', 's/and/or/')
# => "sorwich"
rsub('and/or', 's/\//,/')
# => "and,or"
rsub('stack overflow', 's/o/O/')
# => "stack Overflow"
rsub('stack overflow', 's/o/O/g')
# => "stack OverflOw"
The principle here is you can use a very simple regular expression to parse out your input regular expression and feed that cleaned up data into Regexp.new. There is absolutely no need for eval here, and if anything that severely limits what you can do.
With a little work you could alter that regular expression to parse what's in your existing file and make it do what you want.
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 need a little help with some regex, im fairly new to it all however i feel like this may not be too complex for someone who isnt panicked by regex syntax :)
I have this block of text
{ "NewMessages": "0", "NewAlarms": "0", "Alarms": "13", "PartialAlarms": "", "AckAlarms": "1", "UnusualSens": "",
And need to select the values of each category, only the digit, so far i have selected the whole string with ("Alarms": )"*"\d{1,}"however this obviously also selects Alarms and value, i need just the value of 15, however 15 will change frequently.
Any tips how to select any digits that far after "Alarms" ?
Thanks!
you use the positive lookbehind:
(?<="Alarms": )"*"\d{1,}"
this should work for you
hope it helped :)
You need to put in group.
const regex_alarms = /("Alarms": )"*"(\d{1,})"/mg;
const regex_all = /"\w+": "([0-9]+)"/mg;
Simply:
"Alarms": "(\d*)"
And your value will be in group 1. To get it:
$1
I have the following text:
"BOONS": ["Debarrier+Rainbow Shift"
},
"CLUTCH_BOONS": [
"Boost+Wall"
],
Regex:
(?<=[A-Z a-z])(\+)(?=[A-Z a-z])/g
Using That I am capable of capturing all of the +'s which is great, but I only want to capture the + signs inside of "CLUTCH_BOONS", I have tried really hard with little success.
I also want to close the "BOONS" bracket, I managed to get the left side going properly but cannot get the right quote
(?<=.*)(\")(?=.*\})
end result should look like this
"BOONS": ["Debarrier","Rainbow Shift"]
},
"CLUTCH_BOONS": [
"Boost","Wall"
],
(I was trying to use Atom / regexr to fix problematic json)
For the plus signs, you can use this regex:
"\w+": \[\s*"\w+\K\+
see here:
https://regex101.com/r/fJSl37/1
and for the second one:
"(\s*)},
see here:
https://regex101.com/r/Oy0CiJ/1
I have the following Response Body JSON:
{
"address": [
{
"id": "1234"
}
],
"id": "d1a4f010-48d9-434b-9b3a-2d2b12f5e38c"
}
I am trying to extract the value of the the second "id" field, i.e.
"id": "d1a4f010-48d9-434b-9b3a-2d2b12f5e38c"
I use this Regular Expression in JMeter:
Regular Expression: "id":"(.+?)"
When I run my test, it returns "1234" instead of the guid. How can I change my Regular Expression so that it returns the guid?
Using JMeter, you can use Regular Expression Extractor ...
Reference Name: myid
Regular Expression: "id": "(.+?)"
Template: $1$
Match No.: 2
If you specify using a Match No:...
0 = Random Match
1 = First Match
2 = Second Match
etc....
Or use corresponding variable to access the match. ${myid_2}
The variables are set as follows:
myid_matchNr - Number of matches found, possibly 0
myid_n - (n = 1, 2, etc..) Generated by the template
myid_n_gm - (m = 0, 1, 2) Groups for the match (n)
myid - By itself it is always set to the default value
myid_gn - Not set at all
Or judging by this case, if you prefer just regex and your strings are exactly as stated. You could do..
],\s+"id": "(.+?)"
You can use a lazy regex to find the guid directly instead of finding "id"
Something like this: ([0-9a-z-]{36}).*?
If you are not sure how to create the regex, just use an online regex maker.
I don't know jmeter but to get the value of second id this expression
"id"\s*:.+?"id"\s*:\s*"([^"]*)"
It will return what you want on the $1 variable in a some languages. I suppose in jmeter you can have something similar to this in order to get the first group.
Maybe ${MYREF_g1} according this page ?
The given response values
{
"address": [
{
"id": "1234"
}
],
"id": "d1a4f010-48d9-434b-9b3a-2d2b12f5e38c"
}
Regular Expression to extract the second id values
Regular Expression formats
],\s\s\s\s\s"id": "(.+)"
Note
The above regex extract the following id values
d1a4f010-48d9-434b-9b3a-2d2b12f5e38c
I tried with this:
"id":\s*"([0-9a-f\-]*)"
try with below expression
"id": "([0-9a-z-])*+"
step 1:
id:"1234";
id:(.+?)
"1234"
But we need only the value. So try this,
Step 2:
id:"1234";
id:('(.+?)')
1234