regex for pattern in java - java

I need regex (named in code myRegex) which will match all functions (function1, function2, function3).
public static void main(String[] args) {
String template = "f[0-9]"; // like f1, f2 etc
String myRegex = "fun\\((" + template + "*)\\)"; //todo what regex?
Pattern myPattern = Pattern.compile(myRegex);
String function1 = "fun(f1)";
String function2 = "fun(f1,f9)"; //myRegex don't match
String function3 = "fun(f1,f9,f4)"; // myRegex don't match
List<String> functions = Lists.asList(function1, function2, function3);
for (String function : functions) {
Matcher matcher = myPattern.matcher(function);
while (matcher.find())
{
System.out.println(function + " match!");//works only for function1
}
}
}
Elements in brackets must be seperated by comma (,).
It must work for other funcions with many arguments like
:function4 = "fun(f1,f9,f4,f5,f7)";

Please use below.
String myRegex = "fun\\((" + template + ",)*" + template + "?\\)";
If you want to cater to fun() as well - without any parameters, use below
String myRegex = "fun\\((" + template + ",)*(" + template + ")?\\)";

Use the following regex pattern:
fun\(f[0-9](?:,f[0-9]){0,2}\)
This will match any function named fun() having between 1 and 3 f arguments. Your actual Java regex pattern should be defined as:
Pattern myPattern = Pattern.compile("fun\\(f[0-9](?:,f[0-9]){0,2}\\)");

Regex
Use the following regex. It will also work if there are spaces between arguments or parentheses:
fun\s*\(\s*(?:f[0-9])?(?:\s*,\s*f[0-9])*\s*\)
Demo
https://regex101.com/r/hndzov/1
Java string
Pattern myPattern = Pattern.compile("fun\\s*\\(\\s*(?:f[0-9])?(?:\\s*,\\s*f[0-9])*\\s*\\)")
Explanation
Regex
Description
fun
Match exactly the characters fun
\s
Match any whitespace character
\s*
Match 0 or more whitespaces
\(, \(
Match opening and closing parentheses
f
Match character f
[0-9]
Match any digit from 0-9
(?:)
Make a group but don't capture it
Cons
Also matches a parameter list with a leading comma like fun(,f2, f3).

Related

Regex including date string, email, number

I have this regex expression:
String patt = "(\\w+?)(:|<|>)(\\w+?),";
Pattern pattern = Pattern.compile(patt);
Matcher matcher = pattern.matcher(search + ",");
I am able to match a string like
search = "firstName:Giorgio"
But I'm not able to match string like
search = "email:giorgio.rossi#libero.it"
or
search = "dataregistrazione:27/10/2016"
How I should modify the regex expression in order to match these strings?
You may use
String pat = "(\\w+)[:<>]([^,]+)"; // Add a , at the end if it is necessary
See the regex demo
Details:
(\w+) - Group 1 capturing 1 or more word chars
[:<>] - one of the chars inside the character class, :, <, or >
([^,]+) - Group 2 capturing 1 or more chars other than , (in the demo, I added \n as the demo input text contains newlines).
You can use regex like this:
public static void main(String[] args) {
String[] arr = new String[]{"firstName:Giorgio", "email:giorgio.rossi#libero.it", "dataregistrazione:27/10/2016"};
String pattern = "(\\w+[:|<|>]\\w+)|(\\w+:\\w+\\.\\w+#\\w+\\.\\w+)|(\\w+:\\d{1,2}/\\d{1,2}/\\d{4})";
for(String str : arr){
if(str.matches(pattern))
System.out.println(str);
}
}
output is:
firstName:Giorgio
email:giorgio.rossi#libero.it
dataregistrazione:27/10/2016
But you have to remember that this regex will work only for your format of data. To make up the universal regex you should use RFC documents and articles (i.e here) about email format. Also this question can be useful.
Hope it helps.
The Character class \w matches [A-Za-z0-9_]. So kindly change the regex as (\\w+?)(:|<|>)(.*), to match any character from : to ,.
Or mention all characters that you can expect i.e. (\\w+?)(:|<|>)[#.\\w\\/]*, .

how to parse a double-quote delimited string that can contain escaped double quotes

I need to parse the line from the stream that would look like this: command "string1" "string2" string can contain spaces and escaped double-quotes. I need to split it so that I get command, string1 and string2 as array elements. I think split() with regex matching " but not \" ( .split("(?<!\\\\)\"") ) would do the job, but I hear that that is not a good idea.
Is there any better way of doing this in Java?
Something like that should do the trick, assuming you want to remove the external double quotes when applicable (if you don't, it's just a matter of changing the first capturing group to also include the quotes):
public class Demo {
private static final Pattern WORD =
Pattern.compile("\"((?:[^\\\\\"]|\\\\.)*)\"|([^\\s\"]+)");
public static void main(String[] args) {
String cmd =
"command " +
"\"string with blanks\" " +
"\"anotherStringBetweenQuotes\" " +
"\"a string with \\\"escaped\\\" quotes\" " +
"stringWithoutBlanks";
Matcher matcher = WORD.matcher(cmd);
while (matcher.find()) {
String capturedGroup = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
System.out.println("Matched: " + capturedGroup);
}
}
}
Output:
Matched: command
Matched: string with blanks
Matched: anotherStringBetweenQuotes
Matched: a string with \"escaped\" quotes
Matched: stringWithoutBlanks
The regex is a bit complicated, so it well deserves a bit of explanation:
[^\\\\\"] matches everything but a backslash or double quotes
\\\\. matches a backslash followed by any character (including double quotes), namely escaped characters
(?:[^\\\\\"]|\\\\.)* matches any sequence of escaped or non-escaped characters, but without capturing the group (because of the (?:))
"\"((?:[^\\\\\"]|\\\\.)*)\" matches any such sequence wrapped into double quotes and captures the inside of the quotes
([^\\s\"]+) matches any non-empty sequence of non-blank characters, and captures it in a group

What is wrong in regexp in Java

I want to get the word text2, but it returns null. Could you please correct it ?
String str = "Text SETVAR((&&text1 '&&text2'))";
Pattern patter1 = Pattern.compile("SETVAR\\w+&&(\\w+)'\\)\\)");
Matcher matcher = patter1.matcher(str);
String result = null;
if (matcher.find()) {
result = matcher.group(1);
}
System.out.println(result);
One way to do it is to match all possible pattern in parentheses:
String str = "Text SETVAR((&&text1 '&&text2'))";
Pattern patter1 = Pattern.compile("SETVAR[(]{2}&&\\w+\\s*'&&(\\w+)'[)]{2}");
Matcher matcher = patter1.matcher(str);
String result = "";
if (matcher.find()) {
result = matcher.group(1);
}
System.out.println(result);
See IDEONE demo
You can also use [^()]* inside the parentheses to just get to the value inside single apostrophes:
Pattern patter1 = Pattern.compile("SETVAR[(]{2}[^()]*'&&(\\w+)'[)]{2}");
^^^^^^
See another demo
Let me break down the regex for you:
SETVAR - match SETVAR literally, then...
[(]{2} - match 2 ( literally, then...
[^()]* - match 0 or more characters other than ( or ) up to...
'&& - match a single apostrophe and two & symbols, then...
(\\w+) - match and capture into Group 1 one or more word characters
'[)]{2} - match a single apostrophe and then 2 ) symbols literally.
Your regex doesn't match your string, because you didn't specify the opened parenthesis also \\w+ will match any combinations of word character and it won't match space and &.
Instead you can use a negated character class [^']+ which will match any combinations of characters with length 1 or more except one quotation :
String str = "Text SETVAR((&&text1 '&&text2'))";
"SETVAR\\(\\([^']+'&&(\\w+)'\\)\\)"
Debuggex Demo

Java RegExp Replace

Hello I've been trying to make some replacement with not success
public class demo {
public static void main(String[] args){
String url = "/demoapi/api/user/123";
String newurl = "/user/?user=$1";
Pattern pattern = Pattern.compile("/^\\/demoapi\\/api\\/user\\/([0-9]\\d*)$/i");
Matcher match = pattern.matcher(url);
}
}
I want to replace $1 with 123 , how do I do this ?!
Thank you !
I want to replace $1 with 123 , how do I do this ?!
Simply use replace method but never forget to escape $
"/user/?user=$1".replace(/(\$1)/,"123");
I think you are looking for something like this:
String url = "/demoapi/api/user/123";
String newurl = "/user/?user=$1";
Pattern pattern = Pattern.compile(".*/user/(\\d*)");
Matcher match = pattern.matcher(url);
if(match.matches()){
newurl = newurl.replace("$1", match.group(1));
}
System.out.println(newurl);
Hope this helps.
You don't need to enter the whole text ^\\/demoapi\\/api\\/user\\ in the pattern. Just a ^.*\\/ will match upto the last / symbol. So Your java code would be,
String url = "/demoapi/api/user/123";
String newurl = "/user/?user=$1";
String m1 = url.replaceAll("(?i)^.*\\/([0-9]+)$", "$1");
String m2 = newurl.replaceAll("\\$1", m1);
System.out.println(m2);
Output:
/user/?user=123
Explanation:
(?i) Turn on the case insensitive mode.
^.*\\/ Matches upto the last / symbol.
([0-9]+)$ Captures the last digits.
IDEONE
OR
String url = "/demoapi/api/user/123";
String m1 = url.replaceAll(".*/(\\d*)$", "/user/?user=$1");
You need to put / before (\\d*), so that it would capture the numbers from starting ie, 123. Otherwise it would print the last number ie, 3.
You can use any of the following method :-
public class Test {
public static void main(String[] args) {
public static void main(String[] args) {
String url = "/demoapi/api/user/123";
String newurl = "/user/?user=$1";
String s1 = newurl.replaceAll("\\$1", Matcher.quoteReplacement("123"));
System.out.println("s1 : " + s1);
// OR
String s2 = newurl.replaceAll(Pattern.quote("$1"),Matcher.quoteReplacement("123"));
System.out.println("s2 : " + s2);
// OR
String s3 = newurl.replaceAll("\\$1", "123");
System.out.println("s3 : " + s3);
// OR
String s4 = newurl.replace("$1", "123");
System.out.println("s4 : " + s4);
}
}
Explanation of Methods Used :
Pattern.quote(String s) : Returns a literal pattern String for the
specified String. This method produces a String that can be used to
create a Pattern that would match the string s as if it were a
literal pattern. Metacharacters or escape sequences in the input
sequence will be given no special meaning.
Matcher.quoteReplacement(String s) : Returns a literal replacement
String for the specified String. This method produces a String that
will work as a literal replacement s in the appendReplacement method
of the Matcher class. The String produced will match the sequence of
characters in s treated as a literal sequence. Slashes ('\') and
dollar signs ('$') will be given no special meaning.
String.replaceAll(String regex, String replacement) : Replaces each
substring of this string that matches the given regular expression
with the given replacement.
An invocation of this method of the form str.replaceAll(regex, repl)
yields exactly the same result as the expression
Pattern.compile(regex).matcher(str).replaceAll(repl)
Note that backslashes () and dollar signs ($) in the replacement
string may cause the results to be different than if it were being
treated as a literal replacement string; see Matcher.replaceAll. Use
Matcher.quoteReplacement(java.lang.String) to suppress the special
meaning of these characters, if desired.
String.replace(CharSequence target, CharSequence replacement) :
Replaces each substring of this string that matches the literal
target sequence with the specified literal replacement sequence. The
replacement proceeds from the beginning of the string to the end, for
example, replacing "aa" with "b" in the string "aaa" will result in
"ba" rather than "ab".
Compact Search: .*?(\d+)$
This is all you need:
String replaced = yourString.replaceAll(".*?(\\d+)$", "/user/?user=$1");
In the regex demo, see the substitutions at the bottom.
Explanation
(\d+) matches one or more digits (this is capture Group 1)
The $ anchor asserts that we are at the end of the string
We replace with /user/?user= and Group 1, $1

Java regex patterns

I need help with this matter. Look at the following regex:
Pattern pattern = Pattern.compile("[A-Za-z]+(\\-[A-Za-z]+)");
Matcher matcher = pattern.matcher(s1);
I want to look for words like this: "home-made", "aaaa-bbb" and not "aaa - bbb", but not
"aaa--aa--aaa". Basically, I want the following:
word - hyphen - word.
It is working for everything, except this pattern will pass: "aaa--aaa--aaa" and shouldn't. What regex will work for this pattern?
Can can remove the backslash from your expression:
"[A-Za-z]+-[A-Za-z]+"
The following code should work then
Pattern pattern = Pattern.compile("[A-Za-z]+-[A-Za-z]+");
Matcher matcher = pattern.matcher("aaa-bbb");
match = matcher.matches();
Note that you can use Matcher.matches() instead of Matcher.find() in order to check the complete string for a match.
If instead you want to look inside a string using Matcher.find() you can use the expression
"(^|\\s)[A-Za-z]+-[A-Za-z]+(\\s|$)"
but note that then only words separated by whitespace will be found (i.e. no words like aaa-bbb.). To capture also this case you can then use lookbehinds and lookaheads:
"(?<![A-Za-z-])[A-Za-z]+-[A-Za-z]+(?![A-Za-z-])"
which will read
(?<![A-Za-z-]) // before the match there must not be and A-Z or -
[A-Za-z]+ // the match itself consists of one or more A-Z
- // followed by a -
[A-Za-z]+ // followed by one or more A-Z
(?![A-Za-z-]) // but afterwards not by any A-Z or -
An example:
Pattern pattern = Pattern.compile("(?<![A-Za-z-])[A-Za-z]+-[A-Za-z]+(?![A-Za-z-])");
Matcher matcher = pattern.matcher("It is home-made.");
if (matcher.find()) {
System.out.println(matcher.group()); // => home-made
}
Actually I can't reproduce the problem mentioned with your expression, if I use single words in the String. As cleared up with the discussion in the comments though, the String s contains a whole sentence to be first tokenised in words and then matched or not.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp {
private static void match(String s) {
Pattern pattern = Pattern.compile("[A-Za-z]+(\\-[A-Za-z]+)");
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
System.out.println("'" + s + "' match");
} else {
System.out.println("'" + s + "' doesn't match");
}
}
/**
* #param args
*/
public static void main(String[] args) {
match(" -home-made");
match("home-made");
match("aaaa-bbb");
match("aaa - bbb");
match("aaa--aa--aaa");
match("home--home-home");
}
}
The output is:
' -home-made' doesn't match
'home-made' match
'aaaa-bbb' match
'aaa - bbb' doesn't match
'aaa--aa--aaa' doesn't match
'home--home-home' doesn't match

Categories

Resources