java.util.regex.PatternSyntaxException: Illegal repetition near index 12 - java

I am new to regEx. I need to validate email using java. I have created regEx for email validation by hardcoding the domain name. But the domain name should be dynamic. I have passed the domain name as a parameter. But I don't know how to pass parameter in regEx.
But I tried this code, then I got the error "java.util.regex.PatternSyntaxException: Illegal repetition near index 12". I have followed some answers but it doesn't help for me. From those answers I understood about repetition quantifier. Can you tell me what I am missing here and how to solve this issue?
public static boolean validateEmail(String email, String domainName) {
pattern = Pattern.compile("^([\\w-\\.]+)# {"+ domainName +"}" , Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(email);
return matcher.matches();
}

{ and } have meaning in regex, namely for specifying how often the character before it can repeat. E.g. a{5} matches aaaaa.
If you want to use curly braces in regex, you should escape them like \\{ and \\}.
But that's not what you need for passing this as a parameter — it will just be literal text at that point. If you want to only match that literal domain, you could do Pattern.compile("^([\\w-\\.]+)#" + domainName, Pattern.CASE_INSENSITIVE).

Related

How do I add regex to #Pattern annotation to match one of two specific strings or a null?

I've added #Pattern annotation to a query parameter in my rest controller (SpringBoot Kotlin). I would like the regex in the pattern to accept -
optionA or optionB or null (nothing/an empty string)
The following works, but of course does not include the empty option -
#Pattern(regexp = "(?i)optionA||(?i)optionB")
This does not work -
#Pattern(regexp = "(?i)optionA||(?i)optionB||^\\s*\$")
Can anybody help me with this? :)
Thanks!
Inside the #Pattern annotation, the pattern is used to match the entire string, so you can use
#Pattern(regexp = "(?i)(?:optionA)?")
which is actually \A(?i)(?:optionA)?\z:
\A - start of string (implicit here)
(?i) - case insensitive embedded flag option
(?:optionA)? - an optional non-capturing group that matches optionA or empty string
\z - end of string (implicit here).
The null is a memory address, not a string, it cannot be matched with regex, as regex only deals with strings.
I tryed this optionA|optionB|^\s$ on https://regex101.com/ and worked well. Could you try on your app to check?

Restrict particular domain in email regular expression

I have an existing regex which validates the email input field.
[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!$%&'*+/=?^_`{|}~-]+)*(\\.)?#(?:[a-zA-Z0-9ÄÖÜäöü](?:[a-zA-Z0-9-_ÄÖÜäöü]*[a-zA-Z0-9_ÄÖÜäöü])?\\.)+[a-zA-Z]{2,}
Now, I want this regex to not match for two particular type of email IDs. Which are wt.com and des.net
To do that I made the following changes in the above expression like this.
[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!$%&'*+/=?^_`{|}~-]+)*(\\.)?#(?!wt\\.com)(?!des\\.net)(?:[a-zA-Z0-9ÄÖÜäöü](?:[a-zA-Z0-9-_ÄÖÜäöü]*[a-zA-Z0-9_ÄÖÜäöü])?\\.)+[a-zA-Z]{2,}
After this it does not matches with any email id which ends with the wt.com and des.net which is right.
But the problem is it does not match with wt.comm or any other letter after the restricted string too..
I just want to restrict email which ends with wt.com and des.net
How do I do that?
Below is the sample emails which should match or not.
ajcom#wt.com : no match
ajcom#aa.an : match
ajcom#wt.coms :match
ajcom#des.net : no match
ajcom#des.neta: match
If you want to prevent only wt.com and des.net which have no characters after it you can add $ anchor (which represents end of string) at the end of each negative-look-ahead.
So instead of (?!wt\\.com)(?!des\\.net) use (?!wt\\.com$)(?!des\\.net$)

Replace querystring attribute value in java using regex

I want to replace querystring value but it's creating some problems:
Problem 1: Its Removing the "&" symbol after replacing
String queryString = "?pid=1&name=Dell&cid=25";
String nQueryString=queryString.replaceAll("(?<=[?&;])pid=.*?($|[&;])","pid=23");
System.out.println(nQueryString);
output of above example
?pid=23name=Dell&cid=25
you can see its removed the "&" after pid
Problem 2: Its not working if I removed the "?" symbol from the queryString variable.
String queryString = "pid=1&name=Dell&cid=25";
String nQueryString=queryString.replaceAll("(?<=[?&;])pid=.*?($|[&;])","pid=23");
System.out.println(nQueryString);
output of above example
?pid=1&name=Dell&cid=25
We can say the regex is not working, So anyone can suggest me better regex which completely fulfill my requirements.
queryString.replaceAll("(?<=[?&;])pid=.*?(?=[&;])", "pid=23")
Difference is that I'm using a positive-lookahead: (?=[&;]), which is zero-length, making it atomic, and is not actually included in the replacement via replaceAll(), just like your original positive-lookbehind is not replaced.
Alternatively, we can match until a & or ; is found, but not included in the replacement, ie:
queryString.replaceAll("(?<=[?&;])pid=[^&;]*", "pid=23")
[^&;] : ^ negates the following: &;, so [^&;]* will match until a ; or & is encountered.
Yours does not work because ($|[&;]) is a non-atomic group, specifically a capturing group, and thus is included in the replacement. NB: a non-capturing group (?:$|[&;]) would also fail here.
To your final note, you're using a positive look-behind for ?, &, and ;, so by removing the ?, it will no longer match, which makes sense.
Use this regex instead:
String nQueryString = queryString.replaceAll("(?<=[?&;])pid=[^&]*", "pid=23");
//=> ?pid=23&name=Dell&cid=25
Here [^&]* is called negation matching pattern, that will match query string value until & is found OR else end of string is found thus leaving rest of the query string un-effected.

How to get the particular word from response in jmeter Regular Expression extractor

I am trying to extract the last value from the string in Jmeter Regular Expression extractor.
My string
Server.init("asdfasd4ffffasdf", "http://x.x.x.x:8888/", "asdf-U-Yasdf77asdf99");
I want to get only asdf-U-Yasdf77asdf99.
I tried something like the below, but not correct:
Server.init\(".+", ".+", "([A-Za-z0-9\-]+)"\);
Using JMeter you need to reference your match group.
Reference Name: MYWORD
Regular Expression: Server\.init\("[^"]+", "[^"]+", "([^"]+)"\);
Template: $1$
Your captured match can be accessed by using ${MYWORD}
If you specify using a Match No: above, use the corresponding value to access the match.
That regex, while not very beautiful, should work when used correctly. But you need to look at the result of group 1, not the entire match.
So you need to do something like
Pattern regex = Pattern.compile("Server\\.init\\(\"[^\"]+\", \"[^\"]+\", \"([A-Za-z0-9\\-]+)\"\\);");
Matcher regexMatcher = regex.matcher(subjectString);
if (regexMatcher.find()) {
ResultString = regexMatcher.group(1);
}
Regular Expression:
Server.init\("(.+?)",\s"(.+?)",\s"(.+?)"
Matches the following string
Server.init("asdfasd4ffffasdf", "http://x.x.x.x:8888/", "asdf-U-Yasdf77asdf99"
we can extract the following values in jmeter:
$1 values = asdfasd4ffffasdf
$2 values = http://x.x.x.x:8888/
$3 values = asdf-U-Yasdf77asdf99

Java String Replace Regex

I am doing some string replace in SQL on the fly.
MySQLString = " a.account=b.account ";
MySQLString = " a.accountnum=b.accountnum ";
Now if I do this
MySQLString.replaceAll("account", "account_enc");
the result will be
a.account_enc=b.account_enc
(This is good)
But look at 2nd result
a.account_enc_num=a.account_enc_num
(This is not good it should be a.accountnum_enc=b.accountnum_enc)
Please advise how can I achieve what I want with Java String Replace.
Many Thanks.
From your comment:
Is there anyway to tell in Regex only replace a.account=b.account or a.accountnum=b.accountnum. I do not want accountname to be replace with _enc
If I understand correctly you want to add _enc part only to account or accountnum. To do this you can use
MySQLString = MySQLString.replaceAll("\\baccount(num)?\\b", "$0_enc");
(num)? mean that num is optional so regex will accept account or accountnum
\\b at start mean that there can be no letters, numbers or "_" before account so it wont accept (affect) something like myaccount, or my_account.
\\b at the end will prevent other letters, numbers or "_" after account or accountnum.
It's hard to extrapolate from so few examples, but maybe what you want is:
MySQLString = MySQLString.replaceAll("account\\w*", "$0_enc");
which will append _enc to any sequence of letters, digits, and underscores that starts with account.
try
String s = " a.accountnum=b.accountnum ".replaceAll("(account[^ =]*)", "$1_enc");
it means replace any sequence characters which are not ' ' or '=' which starts the word "account" with the sequence found + "_enc".
$1 is a reference to group 1 in regex; group 1 is the expression in parenthesis (account[^ =]+), i.e. our sequence
See http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for details

Categories

Resources