String str = "hai ${name} .... Welcome to ${sitename}....";
from this str i need to replace ${name} by "jack" and ${sitename} by "google"
is it possible to do with regular Expression ?
or
is there any other fastest way to replace the string .
EDITED :
name and sitename is the str variable is dynamic .
1.So first i have to find the key .
Eg : here name , sitename is the key
2.Then i have an Hashmap which has key value pairs .
based on the key value i have to replace the string in str variable.
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Replacer
{
public static String replacePlaceHolders(String text)
{
Map<String, String> fields = new HashMap<>();
fields.put("name", "jack");
fields.put("sitename", "google");
Pattern p = Pattern.compile("\\$\\{(.*?)\\}");
Matcher matcher = p.matcher(text);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String key = matcher.group(1);
if (!fields.containsKey(key)) {
continue;
}
matcher.appendReplacement(result, fields.get(key));
}
matcher.appendTail(result);
return result.toString();
}
public static void main(String[] args)
{
System.out.println(
replacePlaceHolders("hai ${name} .... Welcome to ${sitename}...."));
}
}
NO Regex is needed!
You could iterate the keySet of your map, and do:
str=str.replace("${"+key+"}", map.get(key));
about the method:
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#replace(java.lang.CharSequence, java.lang.CharSequence)
I think you'd be better off using String.format
String str = String.format("hai %s .... Welcome to %s....", name, site);
Maybe this will help you:
\$\{name+\}
change ${name} to test
-> ${name} trete ${sitename} -> test trete ${sitename}
You have to escape this expression for usage in Java:
\\$\\{name+\\}
If you can replace ${name} and ${sitename} with {0} and {1} you could use MessageFormat.
String str = "hai {0} .... Welcome to {1}....";
String output = MessageFormat.format(str, new String[]{"jack","google"});
Related
I am trying to extract a url from the string. But I am unable to skip the double quotes in the output.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
String s1 = "<a id=\"BUTTON_LINK\" style=\"%%BUTTON_LINK%%\" target=\"_blank\" href=\"https://||domainName||/basketReviewPageLoadAction.do\">%%CHECKOUT%%</a>";
//System.out.println(s1);
Pattern pattern = Pattern.compile("\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))");
Matcher matcher = pattern.matcher(s1);
if(matcher.find()){
String url = matcher.group(1);
System.out.println(url);
}
}
}
My Output is:
"https://||domainName||/basketReviewPageLoadAction.do"
Expected Output is:
https://||domainName||/basketReviewPageLoadAction.do
I cannot do string replace. I have add few get param in this output and attach back it to original string.
Regex: (?<=href=")([^\"]*) Substitution: $1?params...
Details:
(?<=) Positive Lookbehind
() Capturing group
[^] Match a single character not present in the list
* Matches between zero and unlimited times
$1 Group 1.
Java code:
By using function replaceAll you can add your params ?abc=12 to the end of the capturing group $1 in this case href.
String text = "<a id=\"BUTTON_LINK\" style=\"%%BUTTON_LINK%%\" target=\"_blank\" href=\"https://||domainName||/basketReviewPageLoadAction.do\">%%CHECKOUT%%</a>";
text = text.replaceAll("(?<=href=\")([^\"]*)", String.format("$1%s", "?abc=12"));
System.out.print(text);
Output:
<a id="BUTTON_LINK" style="%%BUTTON_LINK%%" target="_blank" href="https://||domainName||/basketReviewPageLoadAction.do?abc=12">%%CHECKOUT%%</a>
Code demo
You can try one of these options:
System.out.println(url.replaceAll("^\"|\"$", ""));
System.out.println(url.substring(1, url.length()-1));
ugly, seems works.Hope this help.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
String s1 = "<a id=\"BUTTON_LINK\" style=\"%%BUTTON_LINK%%\" target=\"_blank\" href= \"https://||domainName||/basketReviewPageLoadAction.do\">%%CHECKOUT%%</a>";
//System.out.println(s1);
Pattern pattern = Pattern.compile("\\s*(?i)href\\s*=\\s*(\"([^\"]*)\"|'([^']*)'|([^'\">\\s]+))");
Matcher matcher = pattern.matcher(s1);
if (matcher.find()) {
String url = Stream.of(matcher.group(2), matcher.group(3),
matcher.group(4)).filter(s -> s != null).collect(Collectors.joining());
System.out.print(url);
}
}
}
This solution worked for now.
Pattern pattern = Pattern.compile("\\s*(?i)href\\s*=\\s*\"([^\"]*)");
You will try this out,
s1 = s1.Replace("\"", "");
this code used for check if word in string in hashMap key
String[] arrs = message.split("(?<! ) |(?<= {2})");
for(int j = 0 ; j < arrs.length; j++){
if(AppConfig.hashMap.containsKey(arrs[j])){
int s = AppConfig.hashMap.get(arrs[j]);
} else
text.append(" "+arrs[j]);
}
and the hashMap its
public static Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
put(":)", R.drawable.emoji_1f60a_64);
put(":D", R.drawable.emoji_1f601_64);
put(":'(", R.drawable.emoji_1f622_64);
put(":P", R.drawable.emoji_1f61c_64);
put(";)", R.drawable.emoji_1f609_64);
put(":O", R.drawable.emoji_1f632_64);
put("-_-", R.drawable.emoji_1f620_64);
put(":*", R.drawable.emoji_1f618_64);
put("<3", R.drawable.emoji_2764_64);
put("^_^", R.drawable.emoji_2764_64);
}};
now its can replace :) with drawable emogi but the problem when i use another smile symbole
when i loop on string and compare every word if found in hashMap
if(AppConfig.hashMap.containsKey(arrs[j])) //found smile replace with emogi
its check if there are :) or :D in string but problem when there are smiles symbols like those
"😌","😃","😄","😞","😢","😷","😓","😰"
so the hashMap will be
public static Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
put("😌", R.drawable.emoji_1f60a_64);
put("😃", R.drawable.emoji_1f601_64);
put("😄", R.drawable.emoji_1f622_64);
put("😞", R.drawable.emoji_1f61c_64);
put("😢", R.drawable.emoji_1f609_64);
put("😷", R.drawable.emoji_1f632_64);
put("😓", R.drawable.emoji_1f620_64);
put("😰", R.drawable.emoji_1f618_64);
}};
here i have this string
hi how are you ? 😌 😃 😄
now when check if there are key in hashMap equal 😌 or 😃 ...
by
if(AppConfig.hashMap.containsKey(arrs[j]))
its fail and say no key with this string
You could create a dynamic pattern from the values in the hashmap (and reuse it because it's expensive to create a pattern it for every execution).
Take a look at https://stackoverflow.com/a/1326962/6709113
For example:
package aa;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
public class Test {
public static String replaceMultipleStrings(String message) {
Map<String,String> tokens = new HashMap<String,String>();
tokens.put("Garfield", "--Garfield--");
tokens.put("😌", "--😌--");
tokens.put("😃", "--😃--");
tokens.put("😄", "--😄--");
// Create pattern of the format "(cat|beverage)"
String patternString = "(" + StringUtils.join(tokens.keySet(), "|") + ")";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(message);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, tokens.get(matcher.group(1)));
}
matcher.appendTail(sb);
String result = sb.toString();
System.out.println(result);
return result;
}
public static void main(String[] args)
{
replaceMultipleStrings("hi how are you, my friend Garfield 😌 😃 😄?");
}
}
The result is: "hi how are you, my friend --Garfield-- --😌-- --😃-- --😄--?"
If performance is required, the HashMap and Pattern creation should be done only once.
I am having a string template containing $variables which needs to be replaced.
String Template: "hi my name is $name.\nI am $age old. I am $sex"
The solution which i tried verifying does not work in the java program.
http://regexr.com/3dtq1
Further, I referred to https://www.regex101.com/ where i could not check if the pattern works for java. But, while going through one of the tutorials I found that "$ Matches end of line". what's the best way to replace the tokens in the template with the variables?
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternCompiler {
static String text = "hi my name is $name.\nI am $age old. I am $sex";
static Map<String,String> replacements = new HashMap<String,String>();
static Pattern pattern = Pattern.compile("\\$\\w+");
static Matcher matcher = pattern.matcher(text);
public static void main(String[] args) {
replacements.put("name", "kumar");
replacements.put("age", "26");
replacements.put("sex", "male");
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
String replacement = replacements.get(matcher.group(1));
if (replacement != null) {
// matcher.appendReplacement(buffer, replacement);
// see comment
matcher.appendReplacement(buffer, "");
buffer.append(replacement);
}
}
matcher.appendTail(buffer);
System.out.println(buffer.toString());
}
}
You are using matcher.group(1) but you didn't define any group in the regexp (( )), so you can use only group() for the whole matched string, which is what you want.
Replace line:
String replacement = replacements.get(matcher.group(1));
With:
String replacement = replacements.get(matcher.group().substring(1));
Notice the substring, your map contains only words, but matcher will match also $, so you need to search in map for "$age".substring(1)" but do replacement on the whole $age.
You can try replacing the pattern string with
\\$(\\w+)
and the variable replacement works. Your current pattern only has group 0 (the entire pattern) but not group 1. Adding the parenthesis makes the first group the variable name and the replacement will replace the dollar sign and the variable name.
Your code has just minor glitches.
static Map<String,String> replacements = new HashMap<>();
static Pattern pattern = Pattern.compile("\\$\\w+\\b"); // \b not really needed
// As no braces (...) there is no group(1)
String replacement = replacements.get(matcher.group());
Your not using the right thing as your key. Change to group(), and change map to '$name' etc:
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HelloWorld {
static String text = "hi my name is $name.\nI am $age old. I am $sex";
static Map<String,String> replacements = new HashMap<String,String>();
static Pattern pattern = Pattern.compile("\\$\\w+");
static Matcher matcher = pattern.matcher(text);
public static void main(String[] args) {
replacements.put("$name", "kumar");
replacements.put("$age", "26");
replacements.put("$sex", "male");
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
String replacement = replacements.get(matcher.group());
System.out.println(replacement);
if (replacement != null) {
// matcher.appendReplacement(buffer, replacement);
// see comment
matcher.appendReplacement(buffer, "");
buffer.append(replacement);
}
}
matcher.appendTail(buffer);
System.out.println(buffer.toString());
}
}
I have a text file and want to tokenize its lines -- but only the sentences with the # character.
For example, given...
Buah... Molt bon concert!! #Postconcert #gintonic
...I want to print only #Postconcert #gintonic.
I have already tried this code with some changes...
public class MyTokenizer {
/**
* #param args
*/
public static void main(String[] args) {
tokenize("Europe3.txt","allo.txt");
}
public static void tokenize(String sFile,String sFileOut) {
String sLine="", sToken="";
MyBufferedReaderWriter f = new MyBufferedReaderWriter();
f.openRFile(sFile);
MyBufferedReaderWriter fOut = new MyBufferedReaderWriter();
fOut.openWFile(sFileOut);
while ((sLine=f.readLine()) != null) {
//StringTokenizer st = new StringTokenizer(sLine, "#");
String[] tokens = sLine.split("\\#");
for (String token : tokens)
{
fOut.writeLine(token);
//System.out.println(token);
}
/*while (st.hasMoreTokens()) {
sToken = st.nextToken();
System.out.println(sToken);
}*/
}
f.closeRFile();
}
}
Can anyone help?
You can try something like with Regex:
package com.stackoverflow.answers;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HashExtractor {
public static void main(String[] args) {
String strInput = "Buah... Molt bon concert!! #Postconcert #gintonic";
String strPattern = "(?:\\s|\\A)[##]+([A-Za-z0-9-_]+)";
Pattern pattern = Pattern.compile(strPattern);
Matcher matcher = pattern.matcher(strInput);
while (matcher.find()) {
System.out.println(matcher.group());
}
}
}
As per the given example, when using the split() function the values would be stored something like this:
tokens[0]=Buah... Molt bon concert!!
tokens[1]=Postconcert
tokens[2]=gintonic
So you just need to skip first value and append '#' (if you need that in your other) to the other string values.
Hope this helps.
You have not specially asked for this, but I assume you try to extract all the #hashtags from your textfile.
To do this, Regex is your friend:
String text = "Buah... Molt bon concert!! #Postconcert #gintonic";
System.out.println(getHashTags(text));
public Collection<String> getHashTags(String text) {
Pattern pattern = Pattern.compile("(#\\w+)");
Matcher matcher = pattern.matcher(text);
Set<String> htags = new HashSet();
while (matcher.find()) {
htags.add(matcher.group(1));
}
return htags;
}
Compile a pattern like this #\w+, everything that starts with a # followed by one or more (+) word character (\w).
Then we have to escape the \ for java with a \\.
And finally put this expression in a group to get access to the matched text by surrounding it with braces (#\w+).
For every match, add the first matched group to the set htags, finally we get a set with all the hashtags in it.
[#gintonic, #Postconcert]
I have the following scenario in my current Java project:
A properties file:
animal1=cat
animal2=dog
A Java method:
public String replace(String input) {
return input.replaceAll("%(.*?)%", properties.getProperty("$1"));
}
The part that says properties.getProperty("$1") obviously doesn't work because it will return the property for the key "$1" but not for the actual value for $1.
Is there any simple method to replace for example "%animal1%" with "cat"?
The properties file will contain a few hundred entries, so searching after a substring that could be replaced for every value in the properties file is not an option.
Don't try to do it as oneliner. If you use a loop to check for all the patterns that might match
Here's some code that will do the trick for you (this should compile and run as-is)
package org.test.stackoverflow;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternReplacer {
private final Pattern keyPattern = Pattern.compile("%([^%]*)%");
private final Properties properties;
public PatternReplacer(Properties propertySeed) {
properties = propertySeed;
}
public String replace(String input) {
int start = 0;
while(true) {
Matcher match = keyPattern.matcher(input);
if(!match.find(start)) break;
String group = match.group(1);
if(properties.containsKey(group)) {
input = input.replaceAll("%" + group + "%", properties.getProperty(group));
} else {
start = match.start() + group.length();
}
}
return input;
}
public static void main(String... args) {
Properties p = new Properties();
p.put("animal1", "cat");
p.put("animal2", "dog");
PatternReplacer test = new PatternReplacer(p);
String result = test.replace("foo %animal1% %bar% %animal2%baz %animal1% qu%ux");
System.out.println(result);
}
}
Output:
foo cat %bar% dogbaz cat qu%ux
If I understand you correctly you will need to use manually use appendReplacement and appendTail methods from Matcher class. This will allow you to pass result of properties.getProperty(matcher.group(1))
Here is basic example of how you can use it. In this example I'm searching for some keyword like string or secret to replace them. Replacement is decided dynamically based on mapping like
string->foo,
secret->whatever
and is determined by simply calling get(keyword) from Map which stores this mapping.
String data = "some string with some secret data";
Map<String,String> properties = new HashMap<>();
properties.put("string", "foo");
properties.put("secret", "whatever");
Pattern p = Pattern.compile("string|secret");
Matcher m = p.matcher(data);
StringBuffer sb = new StringBuffer();
while (m.find()){
m.appendReplacement(sb, properties.get(m.group()));//replace found match
//with result based on group
}
m.appendTail(sb);//append rest of text after last match, in our case " data"
String result = sb.toString();
System.out.println("Original: " + data);
System.out.println("Replaced: " + result);
Result:
Original: some string with some secret data
Replaced: some foo with some whatever data