Matcher, find and replace placeholders with values - regex

I have an input String which is something like a query with placeholders, like this
#input String queryText, test, test2
//queryText is something like " SELECT stuff FROM stufftable WHERE oid_2 = $$test$$ || oid_2 = $$test2$$
Now my task is to replace those placeholders with the content of the inputs, the input variables have the same name of the placeholders, so variable test should replace placeholder $$test$$ and variable test2 should replace placeholder $$test2$$
Here's what I've written down as a test
final List<String> list = new LinkedList<String>();
Pattern pattern = Pattern.compile(/\$\$(.*?)\$\$/)
Matcher matcher = pattern.matcher(queryText)
log.debug(pattern)
while (matcher.find()) {
list.add(matcher.group(1));
String text = matcher.group(1)
log.debug(list)
log.debug(text)
}
And the output I have from the logs is the following:
\$\$(.*?)\$\$
[test]
test
[test, test2]
test2
So the placeholders are found correctly in groups, the part i miss is how to replace the values into them. I've tried .replaceFirst but it loops in the while, I've tried .replaceAll but it replaces all the placeholders at the first time so the others are not even found.
I hope it's clear, it's hard to explain. I'm here for any explanation.

The idea is to put the variables names and their values to a Map, and then use Matcher#appendReplacement to find the variable data in the map by the variable name. The code below is a combination of what the previous answers are about:
// Input:
String queryText = " SELECT stuff FROM stufftable WHERE oid_2 = $$test$$ || oid_2 = $$test2$$";
String test = "1";
String test2 = "2";
Map<String, String> map = new HashMap<>();
map.put("test", test);
map.put("test2", test2);
StringBuffer result = new StringBuffer();
Matcher m = Pattern.compile("\\${2}(.*?)\\${2}").matcher(queryText);
while (m.find()) {
if (!m.group(1).isEmpty()) {
m.appendReplacement(result, map.get(m.group(1)));
}
else {
m.appendReplacement(result, m.group(0));
}
}
m.appendTail(result);
System.out.println(result.toString());
// => SELECT stuff FROM stufftable WHERE oid_2 = 1 || oid_2 = 2
See the Java demo
In Groovy, it is as simple as
String test = "1";
String test2 = "2";
Map map = ["test":test, "test2":test2];
String txt = 'WHERE oid_2 = $$test$$ || oid_2 = $$test2$$';
print txt.replaceAll(/\$\$(.*?)\$\$/) { k -> map[k[1]] ?: k[0] }
See the Groovy demo

String queryText = "SELECT stuff FROM stufftable WHERE oid_2 = $$test$$ || oid_2 = $$test2$$";
String regex="\\$+(.*?)\\$+";
Matcher m=Pattern.compile(regex).matcher(queryText);
StringBuffer sql=new StringBuffer();
while (m.find()) {
m.appendReplacement(sql, "$1");
}
m.appendTail(sql);
System.out.println(sql);
you can try this .

Related

Trim String/Text in Flutter

Hi I tried to trim a link in flutter
Currently I am looking into regexp but I think that is not possible
This is the link in full:
http://sales.local/api/v1/payments/454/ticket/verify?token=jhvycygvjhbknm.eyJpc3MiOiJodH
What I am trying to do is to trim the link like this:
http://sales.local/api/v1/payments/454
Kindly advise on best practise to trim string/text in flutter. Thanks!
try to use substring() :
String link = 'http://sales.local/api/v1/payments/454/ticket/verify?token=jhvycygvjhbknm.eyJpc3MiOiJodH';
String delimiter = '/ticket';
int lastIndex = link.indexOf(delimiter);
String trimmed = link.substring(0,lastIndex);
//print(trimmed);
input string print for Flutter:
String str2 = "-hello Friend- ";
print(str2.trim());
Output Print : -hello Friend-
NOte: Here last space remove from string.
1.Right Method:
var str1 = 'Dart';
var str2 = str1.trim();
identical(str1, str2);
2.Wrong Method
'\tTest String is Fun\n'.trim(); // 'Test String is Fun'
main(List<String> args) {
String str =
'http://sales.local/api/v2/paymentsss/45444/ticket/verify?token=jhvycygvjhbknm.eyJpc3MiOiJodH';
RegExp exp = new RegExp(r"((http|https)://sales.local/api/v\d+/\w.*?/\d*)");
String matches = exp.stringMatch(str);
print(matches); // http://sales.local/api/v2/paymentsss/45444
}

Replace occurence in a String in Kotlin

I have two list of Strings. Now I want to replace every occurence of a word in the first list at index i with a word in the second list at index i of a sentence.
So if I have
list a=("am","I","my")
and
list b=("are","You","your")
I want the sentence "I am an amateur"
to become "You are an amateur"
What is cleanest way to do that in Kotlin (without for loop)?
First split the string to a list of its words and then map each word if it exists in list a to the corresponding word in list b. Finally rejoin the string:
val a= listOf("am","I","my")
val b= listOf("are","You","your")
val str = "I am an amateur"
val new = str
.split("\\s+".toRegex())
.map { val i = a.indexOf(it); if (i < 0) it else b[i] }
.joinToString(" ")
Another way of doing the same thing is:
var new = " $str "
a.forEachIndexed { i, s -> new = new.replace(" $s ", " ${b[i]} ") }
new = new.trim()
although this is closer to a for loop.
I assume there is no punctuation, all whitespaces are spaces and so on.
val m = a.zip(b).toMap()
return s.split(' ').joinToString(" ") { m[it] ?: it }
First you create a map m for more efficient... mapping. Then
Split the string to get a list of words
Map all words: if m contains the word, then return the value (i.e. the replacement), otherwise return the original word (since we shouldn't replace it).
Join all words, separate them by spaces.
You can use the regular expression \b\w+\b to match words in a sentence and then call replace function with the lambda that provides a replacement string for each match:
val input = "I am an amateur, alas."
val wordsToReplace = listOf("I", "am", "my")
val wordsReplaceWith = listOf("You", "are", "your")
val wordRegex = """\b\w+\b""".toRegex()
val result = wordRegex.replace(input) { match ->
val wordIndex = wordsToReplace.indexOf(match.value)
if (wordIndex >= 0) wordsReplaceWith[wordIndex] else match.value
}
println(result)
If there are a lot of word in your lists, it makes sense to build a map of them to speed up searches:
val replaceMap = (wordsToReplace zip wordsReplaceWith).toMap()
val result = wordRegex.replace(input) { match ->
replaceMap[match.value] ?: match.value
}
I think the simplest way is to create a set of regex you want and replace the string by iteration. Let's say you want to replace the word "am", your regex will be "\bam\b". You can use "(?i)\bam\b" if you want it not to be case sensitive. To make "I am an amateur" to "You are an amateur"
val replacements = setOf("\\bam\\b" to "are",
"\\bI\\b" to "You",
"\\bmy\\b" to "your")
replacements.forEach {
str = str.replace(Regex(it.first), it.second)
}

RegularExpression get strings between new lines

I want to taking every string who is located on a new line with Regular Expression
string someStr = "first
second
third
"
example:
string str1 = "first";
string str2 = "second";
string str3 = "third";
Or if you just want the first word of each line;
^(\w+).*$ with multi-line flag.
Regex101 has a nice regex testing tool: https://regex101.com/r/JF3cKR/1
Just split it with "\n";
someStr.split("\n")
And you can filter the empty strings if you'd like
Or if you really want regex, do /^.*$/ with multiline flag
List<String> listOfLines = new ArrayList<String>();
Pattern pattern = Pattern.compile("^.*$", Pattern.MULTILINE);
Matcher matcher = pattern.matcher("first\nsecond\nthird\n");
while (matcher.find()) {
listOfLines.add(matcher.group());
}
Then you have;
listOfLines.get(0) = first
listOfLines.get(1) = second
listOfLines.get(2) = third
You can use the following regex :
(\w+)(?=\n|"|$)
see demo

Tuples from string by regular expressions in Scala

I have string like {param1=foo}{param2=bar}hello world!
I need to extract array of tuples (paramName, value) from this string and get something like [(param1, foo), (param2, bar)]
Is it possible in Scala to extract this tuples by only one regex? Because I managed to do this only in way like
val str = "{param1=foo}{param2=bar}hello world!"
val param = """(?<=\{)(.+?)(?=\})""".r // extract everything between { and }
val keyValue = """(.+)=(.+)""".r // for extracting key and value
val parameters = for (keyValue(key,value) <- param.findAllIn(str).toArray)
yield (key,value)
And it doesn't look sweet.
Also I tried to use
val param = """(?<=\{)(.+?)=(.+?)(?=\})""".r
But it return param=value as one string
Here's an expression that will find things like {A=B} where A and B do not contain {, }, or =.
scala> val Re = """\{([^{}=]+)=([^{}=]+)\}""".r
scala> val Re(a,b) = "{param1=foo}"
a: String = param1
b: String = foo
And if you want to find all matches in a string:
scala> val s = "{param1=foo}{param2=bar}hello world!"
scala> Re.findAllIn(s).matchData.map(_.subgroups).toList
res9: List[List[String]] = List(List(param1, foo), List(param2, bar))
Without regex you can do:
scala> val str = "{param1=foo}{param2=bar}hello world!"
scala> str split '}' filter(x => x.head =='{' && x.contains('=')) map{x => val Array(key, value) = x.tail split '='; key -> value }
res9: Array[(java.lang.String, java.lang.String)] = Array((param1,foo), (param2,bar))
Or in a clearer way:
// We find different blocks
val str1 = str split '}'
// We remove invalid blocks (end of the String in your case)
val str2 = str1 filter(x => x.head == '{' && x.contains('='))
// We transform the String into a tupple, removing the head
val str3 = str2 map{x =>
val Array(key, value) = x.tail split '='
key -> value
}

Count how many times new line is present?

For example,
string="help/nsomething/ncrayons"
Output:
String word count is: 3
This is what I have but the program is looping though the method several times and it looks like I am only getting the last string created. Here's the code block:
Regex regx = new Regex(#"\w+([-+.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*", RegexOptions.IgnoreCase);
MatchCollection matches = regx.Matches(output);
//int counte = 0;
foreach (Match match in matches)
{
//counte = counte + 1;
links = links + match.Value + '\n';
if (links != null)
{
string myString = links;
string[] words = Regex.Split(myString, #"\n");
word_count.Text = words.Length.ToString();
}
}
It is \n for newline.
Not sure if regex is a must for your case but you could use split:
string myString = "help/nsomething/ncrayons";
string[] separator = new string[] { "/n" };
string[] result = myString.Split(separator, StringSplitOptions.None);
MessageBox.Show(result.Count().ToString());
Another way using regex:
string myString = "help/nsomething/ncrayons";
string[] words = Regex.Split(myString, #"/n");
word_count.Text = words.Length;