today I wrote a programm that automaticaly checks if an Netflix account is working or not. But I'm struggling at a point where I need to accept all the country codes in the URL. I wanted to use something like * in linux but my IDE is giving me Errors. What is the Solution and are there better ways?
WebUI.openBrowser('')
WebUI.navigateToUrl('https://www.netflix.com/login')
WebUI.setText(findTestObject('/Page_Netflix/input_email'), 'example#gmail.com')
WebUI.setText(findTestObject('/Page_Netflix/input_password'), '1234')
WebUI.click(findTestObject('/Page_Netflix/button_Sign In'))
TimeUnit.SECONDS.sleep(10)
if (WebUI.getUrl() == "https://www.netflix.com/" + * + "-" + * + "/login") {
}
WebUI.closeBrowser()
So this is your attempt:
if (WebUI.getUrl() == "https://www.netflix.com/" + * + "-" + * + "/login") {
}
which fails, as you can't just use * like that (in addition to using ==, which isn't what you should do when using java). But I think this is what you want:
if (WebUI.getUrl().matches("https://www\\.netflix\\.com/.+-.+/login")) {
// do whatever
}
which would match in whatever country you are in: any url like https://www.netflix.com/it-en/login. If within the if statement you need to use the country information, you'll might want a matcher:
import java.util.regex.*;
Pattern p = Pattern.compile("https://www\\.netflix\\.com/(.+)-(.+)/login");
Matcher m = p.matcher(WebUI.getUrl());
if (m.matches()) {
String country = m.group(1);
String language = m.group(2);
// do whatever
}
Note that we're using java here, as you have the question tagged like that. Katalon is able to use also javascript and groovy, which you've also used in your single-quote strings and leaving out semicolons. In groovy, == for string comparison is ok, and it can also use shorthands for regular expressions.
You could create a list of pair valid values for the country codes if you want to keep track of which country you are in, and the just compare the two strings.
If you don't want to do it that way and accept everything it comes in the url string, then I recommend you using split method:
String sections[] = (WebUI.getUrl()).split("/");
/* Now we have:
sections[0] = "https:""
sections[1] = ""
sections[2] = "www.netflix.com"
sections[3] = whatever the code country is
sections[4] = login
*/
Try to solve it with regular expression on URL string:
final String COUNTRY_CODES_REGEX =
"Country1|Country2|Country3";
Pattern pattern = Pattern.compile(COUNTRY_CODES_REGEX);
Matcher matcher = pattern.matcher(WebUI.getUrl());
if (matcher.find()) {
// Do some stuff.
}
Instead of using WebUI.getUrl() == ...
you could use String.matches (String pattern). Similarly to AutomatedOwl's reply you would define a String variable that is a regex logical-or separated aggregate of the individual country codes. So you have
String country1 = ...
String country2 = ...
String countryN = ...
String countryCodes = String.join("|", country1, country2, countryN);
then you have something along the lines of:
if (WebUI.getUrl().matches("https://www.netflix.com/" + countryCodes + "/login")) {
... do stuff
}
Related
I want to replace particular string values with "XXXX". The issue is the pattern is very dynamic and it won't have a fixed pattern in input data.
My input data
https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme
I need to replace the values of userId and password with "XXXX".
My output should be -
https://internetbanking.abc.co.uk/personal/logon/login/?userId=XXXX&password=XXXX&reme
This is an one off example. There are other cases where only userId and password is present -
userId=12345678&password=stackoverflow&rememberID=
I am using Regex in java to achieve the above, but have not been successful yet. Appreciate any guidance.
[&]([^\\/?&;]{0,})(userId=|password=)=[^&;]+|((?<=\\/)|(?<=\\?)|(?<=;))([^\\/?&;]{0,})(userId=|password=)=[^&]+|(?<=\\?)(userId=|password=)=[^&]+|(userId=|password=)=[^&]+
PS : I am not an expert in Regex. Also, please do let me know if there are any other alternatives to achieve this apart from Regex.
This may cover given both cases.
String maskUserNameAndPassword(String input) {
return input.replaceAll("(userId|password)=[^&]+", "$1=XXXXX");
}
String inputUrl1 =
"https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";
String inputUrl2 =
"userId=12345678&password=stackoverflow&rememberID=";
String input = "https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";
String maskedUrl1 = maskUserNameAndPassword(inputUrl1);
System.out.println("Mask url1: " + maskUserNameAndPassword(inputUrl1));
String maskedUrl2 = maskUserNameAndPassword(inputUrl1);
System.out.println("Mask url2: " + maskUserNameAndPassword(inputUrl2));
Above will result:
Mask url1: https://internetbanking.abc.co.uk/personal/logon/login/?userId=XXXXX&password=XXXXX&reme
Mask url2: userId=XXXXX&password=XXXXX&rememberID=
String url = "https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";
String masked = url.replaceAll("(userId|password)=[^&]+", "$1=XXXX");
See online demo and regex explanation.
Please note, that sending sensitive data via the query string is a big security issue.
I would rather use a URL parser than regex. The below example uses the standard URL class available in java but third party libraries can do it much better.
Function<Map.Entry<String, String>, Map.Entry<String, String>> maskUserPasswordEntries = e ->
(e.getKey().equals("userId") || e.getKey().equals("password")) ? Map.entry(e.getKey(), "XXXX") : e;
Function<List<String>, Map.Entry<String, String>> transformParamsToMap = p ->
Map.entry(p.get(0), p.size() == 1 ? "" : p.get(p.size() - 1));
URL url = new URL("https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme");
String maskedQuery = Stream.of(url.getQuery().split("&"))
.map(s -> List.of(s.split("=")))
.map(transformParamsToMap)
.map(maskUserPasswordEntries).map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining("&"));
System.out.println(url.getProtocol() + "://" + url.getAuthority() + url.getPath() + "?" + maskedQuery);
Output:
https://internetbanking.abc.co.uk/personal/logon/login/?userId=XXXX&password=XXXX&reme=
Just use the methods replace/replaceAll from the String class, they support Charset aswell as regex.
String url = "https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";
url = url.replaceAll("(userId=.+?&)", "userId=XXXX&");
url = url.replaceAll("(password=.+?&)", "password=XXXX&");
System.out.println(url);
I'm not a regex expert either, but if you find it useful, I usually use this website to test my expressions and as a online Cheatsheet:
https://regexr.com
Use:
(?<=(\?|&))(userId|password)=(.*?)(?=(&|$))
(?<=(\?|&)) makes sure it’s preceded by ? or & (but not part of the match)
(userId|password)= matches either userId or password, then =
(.*?) matches any char as long as the next instruction cannot be executed
(?=(&|$)) makes sure the next char is either & or end of the string, (but not part of the match)
Then, replace with $2=xxxxx (to keep userId or password) and choose replaceAll.
For a given plain JSON data do the following formatting:
replace all the special characters in key with underscore
remove the key double quote
replace the : with =
Example:
JSON Data: {"no/me": "139.82", "gc.pp": "\u0000\u000", ...}
After formatting: no_me="139.82", gc_pp="\u0000\u000"
Is it possible with a regular expression? or any other single command execution?
A single regex for the whole changes may be overkill. I think you could code something similar to this:
(NOTE: Since i do not code in java, my example is in javascript, just to get you the idea of it)
var json_data = '{"no/me": "139.82", "gc.pp": "0000000", "foo":"bar"}';
console.log(json_data);
var data = JSON.parse(json_data);
var out = '';
for (var x in data) {
var clean_x = x.replace(/[^a-zA-Z0-9]/g, "_");
if (out != '') out += ', ';
out += clean_x + '="' + data[x] + '"';
}
console.log(out);
Basically you loop through the keys and clean them (remove not-wanted characters), with the new key and the original value you create a new string with the format you like.
Important: Bear in mind overlapping ids. For example, both no/me and no#me will overlap into same id no_me. this may not be important since your are not outputting a JSON after all. I tell you just in case.
I haven't done Java in a long time, but I think you need something like this.
I'm assuming you mean 'all Non-Word characters' by specialchars here.
import java.util.regex.*;
String JsonData = '{"no/me": "139.82", "gc.pp": "\u0000\u000", ...}';
// remove { and }
JsonData = JsonData.substring(0, JsonData.length() - 1);
try {
Pattern regex = Pattern.compile("(\"[^\"]+\")\\s*:"); // find the keys, including quotes and colon
Matcher regexMatcher = regex.matcher(JsonData);
while (regexMatcher.find()) {
String temp = regexMatcher.group(1); // "no/me":
String key = regexMatcher.group(2).replaceAll("\\W", "_") + "="; // no_me=
JsonData.replaceAll(temp, key);
}
} catch (PatternSyntaxException ex) {
// regex has syntax error
}
System.out.println(JsonData);
I'm trying to create a redirect URL for my client. We have a service that you specify "fromUrl" -> "toUrl" that is using a java regex Matcher. But I can't get it work to include the token in when it converts it. For example:
/fromurl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf
Should be:
/tourl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf
but it excludes the token so the result I get is:
/fromurl/login/
/tourl/login/
I tried various regex patterns like: " ?.* and [%5E//?]+)/([^/?]+)/(?.*)?$ and (/*) etc" but no one seems to work.
I'm not that familiar with regex. How can I solve this?
This can be easily done using simple string replace but if you insist on using regular expressions:
Pattern p = Pattern.compile("fromurl");
String originalUrlAsString = "/fromurl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf ";
String newRedirectedUrlAsString = p.matcher(originalUrlAsString).replaceAll("tourl");
System.out.println(newRedirectedUrlAsString);
If I understand you correctly you need something like this?
String from = "/my/old/url/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf";
String to = from.replaceAll("\\/(.*)\\/", "/my/new/url/");
System.out.println(to); // /my/new/url/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf";
This will replace everything between the first and the last forward slash.
Can you detail more exactly what the original expression is like? This is necessary because the regular expression is based on it.
Assuming that the first occurrence of fromurl should simply be replaced with the following code:
String from = "/fromurl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf";
String to = from.replaceFirst("fromurl", "tourl");
But if it is necessary to use more complex rules to determine the substring to replace, you can use:
String from = "/fromurl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf";
String to = "";
String regularExpresion = "(<<pre>>)(fromurl)(<<pos>>)";
Pattern pattern = Pattern.compile(regularExpresion);
Matcher matcher = pattern.matcher(from);
if (matcher.matches()) {
to = from.replaceAll(regularExpresion, "$1tourl$3");
}
NOTE: pre and pos targets are referencial because I don't know the real expresion of the url
NOTE 2: $1 and $3 refer to the first and the third group
Although existing answers should solve the issue and some are similar, maybe below solution would be of help, with quite an easy regex being used (assuming you get input of same format as your example):
private static String replaceUrl(String inputUrl){
String regex = "/.*(/login\\?token=.*)";
String toUrl = "/tourl";
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(inputUrl);
if (matcher.find()) {
return toUrl + matcher.group(1);
} else
return null;
}
You can write a test if it works for other expected inputs/outputs if you want to change format and adjust regex:
String inputUrl = "/fromurl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf";
String expectedUrl = "/tourl/login?token=7c8Q8grW5f2Kz7RP1%2FWsqpVB%2FEluVOGfXQdW4I0v82siR2Ism1D8VCvEmKJr%2BKhHhicwPey0uIiTxN049Be8TNsypf";
if (expectedUrl.equals(replaceUrl(inputUrl))){
System.out.println("Success");
}
I will be given Strings that contain formatted "properties"; that is, Strings encapsulated inside the standard "${" and "}" tokens:
"This is an ${example} of a ${string} that I may be ${given}."
I will also have a HashMap<String,String> containing substitutions for each possible formatted property:
HashMap Keys HashMapValues
===========================================
bacon eggs
ham salads
So that, given the following String:
"I like to eat ${bacon} and ${ham}."
I can send this to a Java method that will transform it into:
"I like to eat eggs and salads."
Here's my best attempt:
System.out.println("Starting...");
String regex = "$\\{*\\}";
Map<String,String> map = new HashMap<String, String>();
map.put("bacon", "eggs");
map.put("ham", "salads");
String sampleString = "I like ${bacon} and ${ham}.";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(sampleString);
while(matcher.find()) {
System.out.println("Found " + matcher.group());
// Strip leading "${" and trailing "}" off.
String property = matcher.group();
if(property.startsWith("${"))
property = property.substring(2);
if(property.endsWith("}"))
property = property.substring(0, property.length() - 1);
System.out.println("Before being replaced, property is: " + property);
if(map.containsKey(property))
property = map.get(property);
// Now, not sure how to locate the original property ("${bacon}", etc.)
// inside the sampleString so that I can replace "${bacon}" with
// "eggs".
}
System.out.println("Ending...");
When I execute this, I get no errors, but just see the "Starting..." and "Ending..." outputs. This tells me that my regex is incorrect, and so the Matcher isn't able to match any properties.
So my first question is: what should this regex be?
Once I'm past that, I'm not sure how to perform the string replace once I've changed "${bacon}" into "eggs", etc. Any ideas? Thanks in advance!
Why don't use a .properties file?, that way you could get all your messages from that file and could be separate from your code, something like (file example.properties):
message1=This is a {0} with format markers on it {1}
And then in your class load your bundle and use it like this:
ResourceBundle bundle = ResourceBundle.getBundle("example.properties", Locale.getDefault());
MessageFormat.format(bundle.getString('message1'), "param0", "param1"); // This gonna be your formatted String "This is a param0 with format markers on it param1"
You could use the MessageFormat (is a java.util library) without the bundle (just use the String directly), but again, having a bundle makes your code clear (and gives easy internationalization)
Use this instead:
String regex = "\\$\\{([^}]*)\\}";
Then you obtain only the content between ${ and } that is inside the capture group 1.
Note that the $ has a special meaning in a pattern: end of the string
Thus it musts be escaped to be seen as literal (as curly brackets).
Better use StrSubstitutor from apache commons lang. It can also substitute System props.
Since commons-lang 3.6 StrSubstitutor has been deprecated in favour of commons-text StringSubstitutor. Example:
import org.apache.commons.text.StringSubstitutor;
Properties props = new Properties();
props.setProperty("bacon", "eggs");
props.setProperty("ham", "salads");
String sampleString = "I like ${bacon} and ${ham}.";
String replaced = StringSubstitutor.replace(sampleString, props);
For completion, here is a working solution:
static final Pattern EXPRESSION_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");
/**
* Replace ${properties} in an expression
* #param expression expression string
* #param properties property map
* #return resolved expression string
*/
static String resolveExpression(String expression, Map<String, String> properties) {
StringBuilder result = new StringBuilder(expression.length());
int i = 0;
Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
while(matcher.find()) {
// Strip leading "${" and trailing "}" off.
result.append(expression.substring(i, matcher.start()));
String property = matcher.group();
property = property.substring(2, property.length() - 1);
if(properties.containsKey(property)) {
//look up property and replace
property = properties.get(property);
} else {
//property not found, don't replace
property = matcher.group();
}
result.append(property);
i = matcher.end();
}
result.append(expression.substring(i));
return result.toString();
}
I have to separate a big list of emails and names, I have to split on commas but some names have commas in them so I have to deal with that first. Luckily the names are between "quotes".
At the moment I get with my regex output like this for example (edit: it doesn't display emails in the forum I see!):
"Talboom, Esther"
"Wolde, Jos van der"
"Debbie Derksen" <deberken#casema.nl>, corine <corine5#xs4all.nl>, "
The last one went wrong cause the name had no comma so it continues until it founds one and that was the one i want to use to separate. So I want it to look until it finds '<'.
How can I do that?
import java.util.regex.Pattern;
import java.util.regex.Matcher;
String test = "\"Talboom, Esther\" <E.Talboom#wegener.nl>, \"Wolde, Jos van der\" <J.vdWolde#wegener.nl>, \"Debbie Derksen\" <deberken#casema.nl>, corine <corine5#xs4all.nl>, \"Markies Aart\" <A.Markies#wegenernieuwsmedia.nl>";
Pattern pattern = Pattern.compile("\".*?,.*?\"");
Matcher matcher = pattern.matcher(test);
boolean found = false;
while (matcher.find ()) {
System.out.println(matcher.group());
}
edit:
better line to work with since not all have a name or quotes:
String test = "\"Talboom, Esther\" <E.Talboom#wegener.nl>, DRP - Wouter Haan <wouter#drp.eu>, \"Wolde, Jos van der\" <J.vdWolde#wegener.nl>, \"Debbie Derksen\" <deberken#casema.nl>, corine <corine5#xs4all.nl>, clankilllller#gmail.com, \"Markies Aart\" <A.Markies#wegenernieuwsmedia.nl>";
I would simplify the code by using String.split and String.replaceAll. This avoids the hassle of working with a Pattern and makes the code neat and brief.
Try this:
public static void main(String[] args) {
String test = "\"Talboom, Esther\" <E.Talboom#wegener.nl>, \"Wolde, Jos van der\" <J.vdWolde#wegener.nl>, \"Debbie Derksen\" <deberken#casema.nl>, corine <corine5#xs4all.nl>, \"Markies Aart\" <A.Markies#wegenernieuwsmedia.nl>";
// Split up into each person's details
String[] nameEmailPairs = test.split(",\\s*(?=\")");
for (String nameEmailPair : nameEmailPairs) {
// Extract exactly the parts you need from the person's details
String name = nameEmailPair.replaceAll("\"([^\"]+)\".*", "$1");
String email = nameEmailPair.replaceAll(".*<([^>]+).*", "$1");
System.out.println(name + " = " + email);
}
}
Output, showing it actually works :)
Talboom, Esther = E.Talboom#wegener.nl
Wolde, Jos van der = J.vdWolde#wegener.nl
Debbie Derksen = corine5#xs4all.nl
Markies Aart = A.Markies#wegenernieuwsmedia.nl