Check if there is any mark after variable value with java regex - java

String url = /aaa/bbbb/cake/123_asd&%?/reg ex+
String variable =cake
if(url.matches(".*"+variable"+'.$'")
I would like to know if there is any mark after variable. This gives me syntax error. Any ide what is the correct syntax?

Yet another way which will display the contents of the URL after the variable:
// Your link string
String link = "/aaa/bbbb/cake/123_asd&%?/reg ex+";
// Your delimiter
String variable = "cake";
// Variable to hold the string contents located
// after the delimiter
String textAfterVar = "";
/*
To fill the textAfterVar string variable we're
going to use the Pattern Matcher method and a small
regex expression for obtaining the string portion
found after our delimiter.
Here we establish our pattern to use and place it into
a variable conveniently named pattern.... */
Pattern pattern = Pattern.compile("(?i).*(" + variable + ")+(.*)");
/*
Breakdown of the expression string: ".*(" + variable + ")+(.*)"
(?i) Ignore letter case. Remove if you want to be case sensitive.
.* Match any character 0 or more times (except newline).
( Group 1 Start...
+variable+ The string variable which holds our delimiter string.
Will be held as Group 1.
) Group 1 End.
+ Match one or more of the previous item which in this case is
the contents of our variable.
( Group 2 Start... This group will be any text after the delimiter.
.* Match any character 0 or more times (except newline).
) Group 2 End. */
/*
We now run the pattern through the matcher method to
see if there is a match to our regex expression. */
Matcher matcher = pattern.matcher(link);
// See if the matcher method finds a match to our expression.
// If so place the contents into the textAfterVar string variable.
if (matcher.find()) { textAfterVar = matcher.group(2); }
// Display the contents of the textAfterVar string
// variable in output console (pane).
System.out.println(textAfterVar);
Hope this helps.

if your String is too long you can try to use find() instead, this way you don't have to match the whole String, but instead what you are interested in (it also makes Regex easier to read too).
Pattern p = Pattern.compile(Pattern.quote(variable) + "[^$]"); //find variable + anything but end of line
Matcher matcher = p.matcher(url);
if(matcher.find()){
System.out.println("matched");
}else{
System.out.println("not matched");
}
Example:
INPUT1:
String url="/aaa/bbbb/cake/123_asd&%?/reg ex+";
String variable="cake";
OUTPUT1:
matched
INPUT2:
String url="/aaa/bbbb/cake/123_asd&%?/reg ex+.";
String variable="ex+.";
OUTPUT2:
not matched

Related

Regex Fetch value from string

I am very new to Regex.
I have String from which i tried fetching value.
String conditionExpression= "{action==\"Submit\" && orgType== \"supply\"}";
Matcher matcher = Pattern.compile("(?<=orgType==)\"[^\"]+\"").matcher(conditionExpression);
if (matcher.find()) {
orgType = matcher.group().replaceAll("\"", "");
}
Input will be String : "{action=="Submit" && orgType== "supply"}"
Output will be value of orgType: supply
Tried fetching orgType using Regex , but its returning null. Anything wrong here?
You need to account for whitespace that may appear around the equals sign. Besides, there is no need to post-process the match value if you use a capturing group around [^"]+.
Here is a fixed code:
String orgType = "";
String conditionExpression= "{action==\"Submit\" && orgType== \"supply\"}";
Matcher matcher = Pattern.compile("orgType\\s*==\\s*\"([^\"]*)\"").matcher(conditionExpression);
if (matcher.find()) {
orgType = matcher.group(1);
}
System.out.println(orgType); // => supply
See the Java demo
The \\s*==\\s* part of the pattern matches == enclosed with 0+ whitespace chars.
The ([^\"]*) pattern is a capturing group that pushes a submatch value into Group 1 that you can retrieve via matcher.group(1) (no need to remove double quotes later).

capture expected result with regex

I am looking for regex with capture group where question mark (?) can be present in my input string. If it is not present it returns the input string as it is, but if ? is present the return the string before the first occurrence of ?.
My input can be in following format
Pattern 1
abc.txt // result should be abc.txt
Pattern 2
abc.txt?param1=qwerty.controller&param2=xsd.txt // result should be abc.txt
I tried below
Matcher matcher = Pattern.compile("(.*?)\\?").matcher(str1);
String group1 = "";
if (matcher.find()) {
group1 = matcher.group();
}
With this I am able to capture expected result for pattern 2, but I am not sure how to modify it so that I can
capture expected result for both pattern 1 and pattern 2.
Update:- I know if group1 is empty string, i can make out that input string does not contain any ? and input string is the expected output here. But i am looking for if i can capture both patterns with single regex ?
You could make use of a negated class like this:
^[^?]+
regex101 demo
^ first makes sure the match starts at the beginning.
[^?]+ matches all non-? characters (if there are none, it will match till the end).
Replace the first ? and everything after it (if it exists):
str = str.replaceAll("\\?.*", "");
One way is to remove everything from your string starting with the first question mark, like this:
String res = orig.replaceAll("[?].*$", "");
If there's no question mark, the expression will match nothing, so you would get the original string. Otherwise, the expression would match everything starting from the question mark, so replaceAll will delete it, because the replacement string is empty.
String orig = "abc.txt?param1=qwerty.controller&param2=xs?d.txt";
String res = orig.replaceAll("[?].*$", "");
System.out.println(res);
orig = "hello world";
res = orig.replaceAll("[?].*$", "");
System.out.println(res);
This prints
abc.txt
hello world
Link to a demo on ideone.
EDIT : I would like to capture both with a single regex
You can use "^[^?]*" for your regex. ^ anchors to the beginning, while [^?] captures everything - either up to the end of the string, or up to the first question mark. Either way, the question mark would be left out.
Here is the code:
String[] strings = new String[] {"abc.txt?param1=qwerty.controller&param2=xs?d.txt", "Hello, world!", "a?b"};
for (String str1 : strings) {
Matcher matcher = Pattern.compile("^[^?]*").matcher(str1);
String group1 = "";
if (matcher.find()) {
group1 = matcher.group();
}
System.out.println(group1);
}
Second demo on ideone.

Excluding markup on lowercased parentheses letters

A string can contain one to many parentheses in lower case letters like String content = "This is (a) nightmare"; I want to transform the string to "<centamp>This is </centamp>(a) <centamp>nightmare</centamp>"; So basically add centamp markup around this string but if it has a lowercase letter in parentheses that should be excluded from the markup.
This is what I have tried so far, but it doesn't achieve the desired result. There could be none to many parentheses in a string and excluding it from the markup should happen for every parentheses.
Pattern pattern = Pattern.compile("^(.*)?(\\([a-z]*\\))?(.*)?$", Pattern.MULTILINE);
String content = "This is (a) nightmare";
System.out.println(content.matches("^(.*)?(\\([a-z]*\\))?(.*)?$"));
System.out.println(pattern.matcher(content).replaceAll("<centamp>$1$3</centamp>$2"));
This can be done in one replaceAll:
String outputString =
inputString.replaceAll("(?s)\\G((?:\\([a-z]+\\))*+)((?:(?!\\([a-z]+\\)).)+)",
"$1<centamp>$2</centamp>");
It allows a non-empty sequence of lower case English alphabet character inside bracket \\([a-z]+\\).
Features:
Whitespace only sequences are tagged.
There will be no tag surrounding empty string.
Explanation:
\G asserts the match boundary, i.e. the next match can only start from the end of last match. It can also match the beginning of the string (when we have yet to find any match).
Each match of the regex will contain a sequence of: 0 or more consecutive \\([a-z]+\\) (no space between allowed), and followed by at least 1 character that does not form \\([a-z]+\\) sequence.
0 or more consecutive \\([a-z]+\\) to cover the case where the string does not start with \\([a-z]+\\), and the case where the string does not contain \\([a-z]+\\).
In the pattern for this portion (?:\\([a-z]+\\))*+ - note that the + after * makes the quantifier possessive, in other words, it disallows backtracking. Simply put, an optimization.
One character restriction is necessary to prevent adding tag that encloses empty string.
In the pattern for this portion (?:(?!\\([a-z]+\\)).)+ - note that for every character, I check whether it is part of the pattern \\([a-z]+\\) before matching it (?!\\([a-z]+\\))..
(?s) flag will cause . to match any character including new line. This will allow a tag to enclose text that spans multiple lines.
You just replace all of the occurence of "([a-z])" with </centamp>$1<centamp> and then prepend <centamp> and append </centamp>
String content = "Test (a) test (b) (c)";
Pattern pattern = Pattern.compile("(\\([a-z]\\))");
Matcher matcher = pattern.matcher(content);
String result = "<centamp>" + matcher.replaceAll("</centamp>$1<centamp>") + "</centamp>";
note I wrote the above in the browser so there may be syntax errors.
EDIT Here's a full example with the simplest RegEx possible.
import java.util.*;
import java.lang.*;
import java.util.regex.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
String content = "test (a) (b) and (c)";
String result = "<centamp>" +
content.replaceAll("(\\([a-z]\\))", "</centamp>$1<centamp>") +
"</centamp>";
result = result.replaceAll("<centamp></centamp>", "");
System.out.print(result);
}
}
This is another solution which uses cleaner regex. The solution is longer, but it allows more flexibility in adjusting the condition to add tag.
The idea here is to match the parenthesis containing lower case characters (the part we don't want to tag), then use the indices from the matches to identify the portion we want to enclose in tag.
// Regex for the parenthesis containing only lowercase English
// alphabet characters
static Pattern REGEX_IN_PARENTHESIS = Pattern.compile("\\([a-z]+\\)");
private static String addTag(String str) {
Matcher matcher = REGEX_IN_PARENTHESIS.matcher(str);
StringBuilder sb = new StringBuilder();
// Index that we have processed up to last append into StringBuilder
int lastAppend = 0;
while (matcher.find()) {
String bracket = matcher.group();
// The string from lastAppend to start of a match is the part
// we want to tag
// If you want to, you can easily add extra logic to process
// the string
if (lastAppend < matcher.start()) { // will not tag if empty string
sb.append("<centamp>")
.append(str, lastAppend, matcher.start())
.append("</centamp>");
}
// Append the parenthesis with lowercase English alphabet as it is
sb.append(bracket);
lastAppend = matcher.end();
}
// The string from lastAppend to end of string (no more match)
// is the part we want to tag
if (lastAppend < str.length()) {
sb.append("<centamp>")
.append(str, lastAppend, str.length())
.append("</centamp>");
}
return sb.toString();
}

How to find expression, evaluate and replace in Java?

I have the following expressions inside a String (that comes from a text file):
{gender=male#his#her}
{new=true#newer#older}
And I would like to:
Find the occurences of that pattern {variable=value#if_true#if_false}
Temporarily store those variables in fields such as variableName, variableValue, ifTrue, ifFalse as Strings.
Evaluate an expression based on variableName and variableValue according to local variables (like String gender = "male" and String new = "true").
And finally replace the pattern with ifTrue or ifFalse according to (3).
Should I use String.replaceAll() in some way, or how do I look for this expression and save the strings that are inside? Thanks for your help
UPDATE
It would be something like PHP's preg_match_all.
UPDATE 2
I solved this by using Pattern and Matcher as I post as an answer below.
If the strings always take this format, then string.split('#') is probably the way to go. This will return an array of strings in the '#' separator (e.g. "{gender=male#his#her}".split('#') = {"{gender=male", "his", "her}"}; use substring to remove the first and last character to get rid of the braces)
After strugling for a while I managed to get this working using Pattern and Matcher as follows:
// \{variable=value#if_true#if_false\}
Pattern pattern = Pattern.compile(Pattern.quote("\\{") + "([\\w\\s]+)=([\\w\\s]+)#([\\w\\s]+)#([\\w\\s]+)" + Pattern.quote("\\}"));
Matcher matcher = pattern.matcher(doc);
// if we'll make multiple replacements we should keep an offset
int offset = 0;
// perform the search
while (matcher.find()) {
// by default, replacement is the same expression
String replacement = matcher.group(0);
String field = matcher.group(1);
String value = matcher.group(2);
String ifTrue = matcher.group(3);
String ifFalse = matcher.group(4);
// verify if field is gender
if (field.equalsIgnoreCase("Gender")) {
replacement = value.equalsIgnoreCase("Female")?ifTrue:ifFalse;
}
// replace the string
doc = doc.substring(0, matcher.start() + offset) + replacement + doc.substring(matcher.end() + offset);
// adjust the offset
offset += replacement.length() - matcher.group(0).length();
}

Regarding String manipulation

I have a String str which can have list of values like below. I want the first letter in the string to be uppercase and if underscore appears in the string then i need to remove it and need to make the letter after it as upper case. The rest all letter i want it to be lower case.
""
"abc"
"abc_def"
"Abc_def_Ghi12_abd"
"abc__de"
"_"
Output:
""
"Abc"
"AbcDef"
"AbcDefGhi12Abd"
"AbcDe"
""
Well, without showing us that you put any effort into this problem this is going to be kinda vague.
I see two possibilities here:
Split the string at underscores, apply the answer from this question to each part and re-combine them.
Create a StringBuilder, walk through the string and keep track of whether you are
at the start of the string
after an underscore or
somewhere else
and act appropriately on the current character before appending it to the StringBuilder instance.
replace _ with space (str.replace("_", " "))
use WordUtils.capitalizeFully(str); (from commons-lang)
replace space with nothing (str.replace(" ", ""))
You can use following regexp based code:
public static String camelize(String input) {
char[] c = input.toCharArray();
Pattern pattern = Pattern.compile(".*_([a-z]).*");
Matcher m = pattern.matcher(input);
while ( m.find() ) {
int index = m.start(1);
c[index] = String.valueOf(c[index]).toUpperCase().charAt(0);
}
return String.valueOf(c).replace("_", "");
}
Use Pattern/Matcher in the java.util.regex package:
for each string that is in your array do the following:
StringBuffer output = new StringBuffer();
Matcher match = Pattern.compile("[^|_](\w)").matcher(inStr);
while(match.find()) {
match.appendReplacement(output, matcher.match(0).ToUpper());
}
match.appendTail(output);
// Will have the properly capitalized string.
String capitalized = output.ToString();
The regular expression looks for either the start of the string or an underscore "[^|_]"
Then puts the following character into a group "(\w)"
The code then goes through each of the matches in the input string capitalizing the first satisfying group.

Categories

Resources