Parsing value from the Jmeter string response - regex

I'm trying to get a value of post_data[‘postcode’] on Jmeter. I tried to parse with JSR223 PostProcessor with the below code but looks like my code is not able to find that variable name.
Response:
<script type="text/javascript">
parent.$("#dialog:ui-dialog").dialog("destroy");
parent.$("#dialog-message div").html("");
var url = '';
var post_data = {};
post_data[‘user’] = “value1”;
post_data[‘city’] = “value2”;
post_data[‘postcode’] = “value3”;
post_data[‘country’] = “value3”;
</script>
JSR223 PostProcessor groovy script:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String stringToSearch=prev.getResponseDataAsString();
Pattern p = Pattern.compile("post_data[‘postcode’] = (\\w+)");
Matcher m = p.matcher(stringToSearch);
if (m.find()){
vars.put("postcode", m.group(1));
}
Any help is greatly appreciated.

You need to surround your match group with quotation marks
You need to escape meta characters
Groovy provides match operator out of box so you can simplify your code as:
vars.put('postcode', (prev.getResponseDataAsString() =~ /post_data\[‘postcode’\] = “(\w+)”/)[0][1])
Demo:
More information:
Groovy Regular Expressions - The Definitive Guide
Apache Groovy - Why and How You Should Use It

Related

Unable to read value from location URL using RegEx inside BeanShell Post Processor

I am using JMeter to automate performance test cases. After HTTP request, I have used RegEx Post Extractor to read the response header. This response header return location. Location is project-specific URL. I want to read the value of the state variable from this URL. For this, I have used BeanShell PostProcessor. For example,
location: "http://www.google.com/state=asdas123123123123&query=asdasdas!##"
I am able to read value of response header as http://www.google.com/state=asdas123123123123&query=asdasdas!##" using regular expression extractor
Then, I have added BeanShell PostProcesssor to read state and query.
import java.util.regex.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
try{
//location = "http://www.google.com/state=asdas123123123123&query=asdasdas!##"
String location = vars.get("location");
String pStr = "/state=(\\S+?)&/"";
Pattern patternN = Pattern.compile(pStr);
Matcher matcher = patternN.matcher(pStr);
if (matcher.find()) {
vars.put("variablename_1",matcher.group(0));
}
vars.put("variablename_2",location);
}catch (Exception ex) {
vars.put("variablename_ex",ex);
throw ex;
}
This code is not working. It seems double slash is creating problems.
Since JMeter 3.1 you should be using JDR223 Test Elements and Groovy language for scripting
Groovy provides Find operator which looks like =~
Assuming above 2 points you can refactor your "code" to this one-liner:
vars.put('variablename_1', (vars.get('location') =~ /state=(\w+)&/)[0][1])
Demo:
More information:
Pattern Matching in Strings in Groovy
Apache Groovy - Why and How You Should Use It

Jmeter - find with regex and replace part of XML body using groovy

I'm trying to replace part an XML response data with something else.
Here is an example:
?xml version="1.0" encoding="UTF-8"?>
<trustedDevices><trustedDevice><id>1942</id><name>BksQ9LKwWuNOHpn</name></trustedDevice><trustedDevice><id>1944</id><name>6f4srs4PkJk1j36</name></trustedDevice><trustedDevice><id>1943</id><name>7cGYVAlmQoXaVrf</name></trustedDevice></trustedDevices>
I'm trying to get all the <name>(.+?)<\/name> data and replace it with something else (timestamp or random string)
so far, my groovy post processor code looks like this:
String trustedDevices = prev.getResponseDataAsString()
log.info('Response: ' + trustedDevices)
def nameFind = "/<name>(.+?)<\/name>/"
def newTrustedDevices = trustedDevices.replaceAll(nameFind, "test")
log.info('New response: ' + newTrustedDevices)
Unfortunately it seems that replaceAll requires String or Long to work, and won't work with regex.
You regex just need a correct escaping:
def nameFind = "<name>(.+?)<\\/name>"
Replacing values in XML using regular expressions is not the best option as it will be fragile and very sensitive to any markup change.
I would suggest going for Groovy's XML parsing capabilities instead
Example code:
def trustedDevices = new XmlSlurper().parseText(prev.getResponseDataAsString())
trustedDevices.trustedDevice.findAll().each {
it.name = 'test'
}
def newTrustedDevices = new StreamingMarkupBuilder().bind { mkp.yield trustedDevices }.toString()
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It

Unable to capture required string from text file using Groovy - Jmeter JSR223

I need to parse a text file testresults.txt and capture serial number and then write the captured serial number onto separate text file called serialno.txt using groovy Jmeter JSR223 post processor.
Below code is not working. It didn't get into the while loop itself. Kindly help.
import java.util.regex.Pattern
import java.util.regex.Matcher
String filecontent = new File("C:/device/resources/testresults.txt").text
def regex = "SerialNumber\" value=\"(.+)\""
java.util.regex.Pattern p = java.util.regex.Pattern.compile(regex)
java.util.regex.Matcher m = p.matcher(filecontent)
File SN = new File("C:/device/resources/serialno.txt")
while(m.find()) {
SN.write m.group(1)
}
If your code doesn't enter the loop it means that there are no matches so you need to amend your regular expression, you can use i.e. Regex101 website for experiments
Given the following content of the testresults.txt file:
SerialNumber" value="foo"
SerialNumber" value="bar"
SerialNumber" value="baz"
your code works fine.
For the time being I can only suggest using match operator to make your code more "groovy"
def source = new File('C:/device/resources/testresults.txt').text
def matches = (source =~ 'SerialNumber" value="(.+?)"')
matches.each { match ->
new File('C:/device/resources/serialno.txt') << match[1] << System.getProperty('line.separator')
}
Demo:
More information: Apache Groovy - Why and How You Should Use It

Regex from Python to Kotlin

I have a question about Regular Expression (Regex) and I really newbie in this. I found a tutorial a Regex written in Python to delete the data and replace it with an empty string.
This is the code from Python:
import re
def extract_identity(data, context):
"""Background Cloud Function to be triggered by Pub/Sub.
Args:
data (dict): The dictionary with data specific to this type of event.
context (google.cloud.functions.Context): The Cloud Functions event
metadata.
"""
import base64
import json
import urllib.parse
import urllib.request
if 'data' in data:
strjson = base64.b64decode(data['data']).decode('utf-8')
text = json.loads(strjson)
text = text['data']['results'][0]['description']
lines = text.split("\n")
res = []
for line in lines:
line = re.sub('gol. darah|nik|kewarganegaraan|nama|status perkawinan|berlaku hingga|alamat|agama|tempat/tgl lahir|jenis kelamin|gol darah|rt/rw|kel|desa|kecamatan', '', line, flags=re.IGNORECASE)
line = line.replace(":","").strip()
if line != "":
res.append(line)
p = {
"province": res[0],
"city": res[1],
"id": res[2],
"name": res[3],
"birthdate": res[4],
}
print('Information extracted:{}'.format(p))
In the above function, information extraction is done by removing all e-KTP labels with regular expressions.
This is the sample of e-KTP:
And this is the result after scanning that e-KTP using the python code:
Information extracted:{'province': 'PROVINSI JAWA TIMUR', 'city': 'KABUPATEN BANYUWANGI', 'id': '351024300b730004', 'name': 'TUHAN', 'birthdate': 'BANYUWANGI, 30-06-1973'}
This is the full tutorial from the above code.
And then my question is, can we use Regex in Kotlin to remove the label from the result of e-KTP like in python code? Because I try some logic that I understand it does not remove the label of e-KTP. My code in Kotlin like this:
....
val lines = result.text.split("\n")
val res = mutableListOf<String>()
Log.e("TAG LIST STRING", lines.toString())
for (line in lines) {
Log.e("TAG STRING", line)
line.matches(Regex("gol. darah|nik|kewarganegaraan|nama|status perkawinan|berlaku hingga|alamat|agama|tempat/tgl lahir|jenis kelamin|gol darah|rt/rw|kel|desa|kecamatan"))
line.replace(":","")
if (line != "") {
res.add(line)
}
Log.e("TAG RES", res.toString())
}
Log.e("TAG INSERT", res.toString())
tvProvinsi.text = res[0]
tvKota.text = res[1]
tvNIK.text = res[2]
tvNama.text = res[3]
tvTgl.text = res[4]
....
And this is the result of my code:
TAG LIST STRING: [PROVINSI JAWA BARAP, KABUPATEN TASIKMALAYA, NIK 320625XXXXXXXXXX, BRiEAFAUZEROMARA, Nama, TempatTgiLahir, Jenis keiamir, etc]
TAG INSERT: [PROVINSI JAWA BARAP, KABUPATEN TASIKMALAYA, NIK 320625XXXXXXXXXX, BRiEAFAUZEROMARA, Nama, TempatTgiLahir, Jenis keiamir, etc]
The label still exists, It's possible to remove a label using Regex or something in Kotlin like in Python?
The point is to use kotlin.text.replace with a Regex as the search argument. For example:
text = text.replace(Regex("""<REGEX_PATTERN_HERE>"""), "<REPLACEMENT_STRING_HERE>")
You may use
line = line.replace(Regex("""(?i)gol\. darah|nik|kewarganegaraan|nama|status perkawinan|berlaku hingga|alamat|agama|tempat/tgl lahir|jenis kelamin|gol darah|rt/rw|kel|desa|kecamatan"""), "")
Note that (?i) at the start of the pattern is a quick way to make the whole pattern case insensitive.
Also, when you need to match a . with a regex you need to escape it. Since a backslash can be coded in several ways and people often fail to do it correctly, it is always recommended to define regex patterns within raw string literals, in Kotlin, you may use the triple-double-quoted string literals, i.e. """...""" where each \ is treated as a literal backslash that is used to form regex escapes.

How do I linkify text using ActionScript 3

I have a text that I want to linkify (identify URLs and convert them to HTML links). The text could be multi-line, and could contain multiple urls like the example below.
My current actionscript code looks like this
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private function init():void {
var str:String = "#stack the website for google is http://www.google.com and gmail is http://gmail.com";
//Alert.show(linkify(str),"Error");
txtStatus.htmlText = linkify(str);
}
private function linkify(texty:String):String {
//return texty.replace("/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g",function(m):String { return m.linkify(m);});
//return texty.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g, function(m):String {return m.linkify(m);}).replace(/(^|[^\w])(#[\d\w\-]+)/g, function(m2):String{return '#' + m2.substr(1) + ''; });
var pattern:RegExp = /[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g;
var match:String = pattern.exec(texty);
return texty.replace(pattern,'<a href="' + match + '">' +
match + '</a>');
}
]]>
</mx:Script>
The problem with the above script is that it recognizes the first match and uses that across. Also how do i do it for #?
Any help is highly appreciated.
ooph ... why does everybody use regex these days, to accomplish super simple tasks? also, you forgot, that "+" is a valid character for URLs, as a replacement for space, and even an awful lot of other characters may be used, so your pattern would not even match accordingly ...
well, anyway, have a look at AS3 regex metacharacters ...
that'll GREATLY improve your expression's readability and is much more robust...
i'd go with something like this, really:
var r:RegExp = /(?:http|https):\/\/\S*/g;
trace(str.replace(r, function (s:String,...rest):String {
return '' + s + ''
} ));
but the actual point, was the global flag ...
good luck then ... :)
greetz
back2dos