It's probably easiest if I just give examples...
I have input data that looks like this:
/foo/blah/something/this
And some that looks like this:
/foo/blah/this
I need a regex that will match the latter but not the former.
In other words:
/foo/*/this should match
/foo/*/*/this should not match
"foo" is a static value, meaning it is always "foo" and "this" is the same. The 'blah' and 'something' represent variables that could be anything.
So, the following strings SHOULD be matched by my regex:
/foo/john/jones
/foo/james/jones
/foo/steven/jones
/foo/samantha/jones
but the following strings should NOT match:
/foo/john/paul/jones
/foo/james/earl/jones
/foo/steven/james/jones
/foo/samantha/wilson/jones
Any help?
^/foo/[^/]+/[^/]+$
You can replace [^/]+ with [^/]* if you want stuff like /foo//jones to work as well.
You can use regex for this and also the matches method of the string class to match the strings:
sample:
String[] s = {"/foo/john/jones", "/foo/james/jones", "/foo/john/paul/jones", "/foo/james/earl/jones"};
for(String s2 : s)
System.out.println(s2.matches("/foo/([^/]+)/jones"));
result:
true
true
false
false
You can use this regex:
^/\w+/\w+/\w+$
Working demo
Thanks Pshemo for the comment. I forgot to mention that for java you need to escape backslashes and / doesn't need to be escaped.
So, the java regex would be:
^/\\w+/\\w+/\\w+$
By the way, a nice Pschemo observation is that if you have /foo as static value. You could use this regex:
^/foo/\\w+/\\w+$
You can also do this without a regex:
public boolean isValid(String expression) {
if (!expression.startsWith("/foo/") {
return false;
}
String[] parts = expression.split("/");
// note: four including the empty string before the first slash
return parts.length == 4;
}
Related
String 1= abc/{ID}/plan/{ID}/planID
String 2=abc/1234/plan/456/planID
How can I match these two strings using Java regex so that it returns true? Basically {ID} can contain anything. Java regex should match abc/{anything here}/plan/{anything here}/planID
If your "{anything here}" includes nothing, you can use .*. . matches any letter, and * means that match the string with any length with the letter before, including 0 length. So .* means that "match the string with any length, composed with any letter". If {anything here} should include at least one letter, you can use +, instead of *, which means almost the same, but should match at least one letter.
My suggestion: abc/.+/plan/.+/planID
If {ID} can contain anything I assume it can also be empty.
So this regex should work :
str.matches("^abc.*plan.*planID$");
^abc at the beginning
.* Zero or more of any Character
planID$ at the end
I am just writing a small code, just check it and start making changes as per you requirement. This is working, check for your other test cases, if there is any issue please comment that test case. Specifically I am using regex, because you want to match using java regex.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class MatchUsingRejex
{
public static void main(String args[])
{
// Create a pattern to be searched
Pattern pattern = Pattern.compile("abc/.+/plan/.+/planID");
// checking, Is pattern match or not
Matcher isMatch = pattern.matcher("abc/1234/plan/456/planID");
if (isMatch.find())
System.out.println("Yes");
else
System.out.println("No");
}
}
If line always starts with 'abc' and ends with 'planid' then following way will work:
String s1 = "abc/{ID}/plan/{ID}/planID";
String s2 = "abc/1234/plan/456/planID";
String pattern = "(?i)abc(?:/\\S+)+planID$";
boolean b1 = s1.matches(pattern);
boolean b2 = s2.matches(pattern);
I am trying to write regular expression in Java to evaluate two strings mentioned with () separated by ,
Example: (test1,test2)
I have written below code
public static void main(String[] a){
String pattern = "\\([a-zA-Z0-9]+,[a-zA-Z0-9]+.\\)";
String test = "(test1,test2)";
System.out.println(test.matches(pattern));
}
It works as expected and prints true in below cases
String test = "(test1,test2)";
String test = "(t,test2)";
But it is printing false when I send below
String test = "(test1,t)";
It is strange because I am using same expression before and after ,
It returns true for (t,test2) but not for (test1,t)
Please let me know what am I missing in this regular expression. I need it to evaluate and return true for (test1,t)
There's no need for the . (that matches one character) in your regex. Remove . from your regex so it becomes "\\([a-zA-Z0-9]+,[a-zA-Z0-9]+\\)" and it should work.
Use this regex:
String pattern = "^\\(.+,.+\\)";
This will match your required strings.
In the second part of your pattern, you have "[a-zA-Z0-9]+."
If you're trying to match "t", it will see t for the [a-zA-Z0-9]+ part, but it requires another character after that to match the . part.
Revised pattern: "\\([a-zA-Z0-9]+,[a-zA-Z0-9]+\\)"
Delete the dot after the second group[a-zA-Z0-9]
Demo
and even simpler you can use \w for words, you can use instead of [a-zA-Z0-9]
so your regular expression would be like that
\(\w+,\w+\)
In your regular expression '.' is not needed in the latter part.
change is as "\([a-zA-Z0-9]+,[a-zA-Z0-9]+\)" so that it will be returning true for "(test,t)"
String pattern = "\\([a-zA-Z0-9]+,[a-zA-Z0-9]+\\)";
String test = "(te,t)";
System.out.println(test.matches(pattern)); // true
String pattern = "\\([a-zA-Z0-9]+,[a-zA-Z0-9]+\\)";
String test = "(test1,test2)";
String t1 = "(t,test2)";
String t2="(test2,t)";
System.out.println(test.matches(pattern));
System.out.println(t1.matches(pattern));
System.out.println(t2.matches(pattern));
just try this code, it will give you answer you want.
You have written "." at the end after + in your pattern so clear it.
I have strings that I need to use regex to replace a specific character. The strings are in the following format:
"abc.edf" : "abc.abc", "ghi.ghk" : "bbb.bbb" , "qwq.tyt" : "ddd.ddd"
I need to replace the periods, '.', that are between the strings in quotes before the colon but not the strings in quotes after the colon and before the comma. Could someone shed some light?
This pattern will match the entire part that you want to touch: "\w{3}\.\w{3}" : "\w{3}\.\w{3}". Since it includes the colon and the values on both side, it won't match ones where there is a comma between the values. Depending on your needs, you may need to change \w to some other character class.
But, as I'm sure you are aware, you don't want to replace the entire string. You only want to replace the one character. There are two ways to do that. You can either use look-aheads and look-behinds to exclude everything else except the period from the resulting match:
Pattern: (?<="\w{3})\.(?=\w{3}" : "\w{3}\.\w{3}")
Replacement: :
Or, if the look-aheads and look-behinds confuse you, you could just capture the whole thing and include the original values from the captured groups in the replacement value:
Pattern: ("\w{3})\.(\w{3}" : "\w{3}\.\w{3}")
Replacement: $1:$2
Try with the following patern: /.(?=[a-z]+)/g
Working regex-demo for substitution # regex101
Java Working Demo:
public class StackOverFlow31520446 {
public static String text;
public static String pattern;
public static String replacement;
static {
text = "\"abc.edf\" : \"123.231\", \"ghi.ghk\" : \"456.678\" , \"qwq.tyt\" : \"141.242\"";
pattern = "\\.(?=[a-z]+)";
replacement = ";";
}
public static String replaceMatches(String text, String pattern, String replacement) {
return text.replaceAll(pattern, replacement);
}
public static void main(String[] args) {
System.out.println(replaceMatches(text, pattern, replacement));
}
}
Not sure what you intend to do with the string but this is a way to
match the contents of the quote's.
The contents are in capture buffer 1.
You could use a callback to replace the dots within the
contents, passing that back within the main replacement function.
Find: "([^"]*\.[^"]*)"(?=\s*:)
Replace: " + func( call to replace dots from capt buff 1 ) + "
Formatted:
" # Open quote
( [^"]* \. [^"]* ) # (1), group 1 - contents
" # Close quote
(?= # Lookahead, must be a colon
\s*
:
)
If would go for a different approach (maybe it is even faster). In your loop over all strings first try if the string matches a number \d*\.?\d* - if not, do the replacement of . with : (without any regexp).
Would that solve your problem?
You can do it without look arounds:
str = str.replaceAll("(\\D)\\.(\\D)", "$1:$2");
should be sufficient for the task.
I want to remove parenthesis using Java regular expression but I faced to error No group 1 please see my code and help me.
public String find_parenthesis(String Expr){
String s;
String ss;
Pattern p = Pattern.compile("\\(.+?\\)");
Matcher m = p.matcher(Expr);
if(m.find()){
s = m.group(1);
ss = "("+s+")";
Expr = Expr.replaceAll(ss, s);
return find_parenthesis(Expr);
}
else
return Expr;
}
and it is my main:
public static void main(String args[]){
Calculator c1 = new Calculator();
String s = "(4+5)+6";
System.out.println(s);
s = c1.find_parenthesis(s);
System.out.println(s);
}
The simplest method is to just remove all parentheses from the string, regardless of whether they are balanced or not.
String replaced = "(4+5)+6".replaceAll("[()]", "");
Correctly handling the balancing requires parsing (or truly ugly REs that only match to a limited depth, or “cleverness” with repeated regular expression substitutions). For most cases, such complexity is overkill; the simplest thing that could possibly work is good enough.
What you want is this: s = s.replaceAll("[()]","");
For more on regex, visit regex tutorial.
You're getting the error because your regex doesn't have any groups, but I suggest you use this much simpler, one-line approach:
expr = expr.replaceAll("\\((.+?)\\)", "$1");
You can't do this with a regex at all. It won't remove the matching parentheses, just the first left and the first right, and then you won't be able to get the correct result from the expression. You need a parser for expressions. Have a look around for recursive descent ezpresssion parsers, the Dijkstra shunting-yard algorithm, etc.
The regular expression defines a character class consisting of any whitespace character (\s, which is escaped as \s because we're passing in a String), a dash (escaped because a dash means something special in the context of character classes), and parentheses. Try it working code.
phoneNumber.replaceAll("[\\s\\-()]", "");
I know I'm very late here. But, just in case you're still looking for a better answer. If you want to remove both open and close parenthesis from a string, you can use a very simple method like this:
String s = "(4+5)+6";
s=s.replaceAll("\\(", "").replaceAll("\\)","");
If you are using this:
s=s.replaceAll("()", "");
you are instructing the code to look for () which is not present in your string. Instead you should try to remove the parenthesis separately.
To explain in detail, consider the below code:
String s = "(4+5)+6";
String s1=s.replaceAll("\\(", "").replaceAll("\\)","");
System.out.println(s1);
String s2 = s.replaceAll("()", "");
System.out.println(s2);
The output for this code will be:
4+5+6
(4+5)+6
Also, use replaceAll only if you are in need of a regex. In other cases, replace works just fine. See below:
String s = "(4+5)+6";
String s1=s.replace("(", "").replace(")","");
Output:
4+5+6
Hope this helps!
I am writing Java code that has to distinguish regular expressions with more than one possible match from regular expressions that have only one possible match.
For example:
"abc." can have several matches ("abc1", abcf", ...),
while "abcd" can only match "abcd".
Right now my best idea was to look for all unescaped regexp special characters.
I am convinced that there is a better way to do it in Java. Ideas?
(Late addition):
To make things clearer - there is NO specific input to test against. A good solution for this problem will have to test the regex itself.
In other words, I need a method who'se signature may look something like this:
boolean isSingleResult(String regex)
This method should return true if only for one possible String s1. The expression s1.matches(regex) will return true. (See examples above.)
This sounds dirty, but it might be worth having a look at the Pattern class in the Java source code.
Taking a quick peek, it seems like it 'normalize()'s the given regex (Line 1441), which could turn the expression into something a little more predictable. I think reflection can be used to tap into some private resources of the class (use caution!). It could be possible that while tokenizing the regex pattern, there are specific indications if it has reached some kind "multi-matching" element in the pattern.
Update
After having a closer look, there is some data within package scope that you can use to leverage the work of the Pattern tokenizer to walk through the nodes of the regex and check for multiple-character nodes.
After compiling the regular expression, iterate through the compiled "Node"s starting at Pattern.root. Starting at line 3034 of the class, there are the generalized types of nodes. For example class Pattern.All is multi-matching, while Pattern.SingleI or Pattern.SliceI are single-matching, and so on.
All these token classes appear to be in package scope, so it should be possible to do this without using reflection, but instead creating a java.util.regex.PatternHelper class to do the work.
Hope this helps.
If it can only have one possible match it isn't reeeeeally an expression, now, is it? I suspect your best option is to use a different tool altogether, because this does not at all sound like a job for regular expressions, but if you insist, well, no, I'd say your best option is to look for unescaped special characters.
The only regular expression that can ONLY match one input string is one that specifies the string exactly. So you need to match expressions with no wildcard characters or character groups AND that specify a start "^" and end "$" anchor.
"the quick" matches:
"the quick brownfox"
"the quick brown dog"
"catch the quick brown fox"
"^the quick brown fox$" matches ONLY:
"the quick brown fox"
Now I understand what you mean. I live in Belgium...
So this is something what work on most expressions. I wrote this by myself. So maybe I forgot some rules.
public static final boolean isSingleResult(String regexp) {
// Check the exceptions on the exceptions.
String[] exconexc = "\\d \\D \\w \\W \\s \\S".split(" ");
for (String s : exconexc) {
int index = regexp.indexOf(s);
if (index != -1) // Forbidden char found
{
return false;
}
}
// Then remove all exceptions:
String regex = regexp.replaceAll("\\\\.", "");
// Now, all the strings how can mean more than one match
String[] mtom = "+ . ? | * { [:alnum:] [:word:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:]".split(" ");
// iterate all mtom-Strings
for (String s : mtom) {
int index = regex.indexOf(s);
if (index != -1) // Forbidden char found
{
return false;
}
}
return true;
}
Martijn
I see that the only way is to check if regexp matches multiple times for particular input.
package com;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AAA {
public static void main(String[] args) throws Exception {
String input = "123 321 443 52134 432";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(input);
int i = 0;
while (matcher.find()) {
++i;
}
System.out.printf("Matched %d times%n", i);
}
}