java regular expression - java

I have a string like this
STAR=20110209
00:01:01|PNAM=test_.xml|PNUM=480|SSTA=20110209
00:01:01|STRT=20110209
00:01:01|STOP=20110209 00:01:01|
and i want to extract values of few of the keys here.
like whats the value of PNAM and SSTA.
I want a regular expression that can provide the values of few of the keys and keys can be in any order.

Would something like this work for you?
String str = "STAR=20110209 00:01:01|PNAM=test_.xml|PNUM=480|SSTA=20110209 00:01:01|STRT=20110209 00:01:01|STOP=20110209 00:01:01";
String[] parts = str.split("\\|");
for (String part : parts)
{
String[] nameValue = part.split("=");
if (nameValue[0] == "somekey")
{
// ..
}
}

So, the way your problem is really isn't best solved with regular expressions. Instead, use split() like someone else has offered, but instead of having a crazy if loop, load everything into a map.
String str = "STAR=20110209 00:01:01|PNAM=test_.xml|PNUM=480|SSTA=20110209 00:01:01|STRT=20110209 00:01:01|STOP=20110209 00:01:01";
String[] parts = str.split("|");
Map<String, String> properties = new HashMap<String, String>();
for (String part : parts) {
String[] nameValue = part.split("=");
properties.put(nameValue[0], nameValue[1]);
}
Then all you have to do is, properties.get("PNUM")

Use this Java code:
String str = "STAR=20110209 00:01:01|PNAM=test_.xml|PNUM=480|SSTA=20110209 00:01:01|STRT=20110209 00:01:01|STOP=20110209 00:01:01|";
Pattern p = Pattern.compile("([^=]*)=([^|]*)\\|");
Matcher m = p.matcher(str);
String pnamVal = null, sstaVal = null;
while (m.find()) {
//System.out.println("Matched: " + m.group(1) + '=' + m.group(2));
if (m.group(1).equals("PNAM"))
pnamVal = m.group(2);
else if (m.group(1).equals("SSTA"))
sstaVal = m.group(2);
if (pnamVal != null && sstaVal != null)
break;
}
System.out.println("SSTA: " + sstaVal);
System.out.println("PNAM: " + pnamVal);
OUTPUT
SSTA: 20110209 00:01:01
PNAM: test_.xml

Related

How to get exact match keyword from the given string using java?

I'm trying to match exact AdvanceJava keyword with the given inputText string but it executes both if and else condition,instead of I want only AdvanceJava keyword matched.
String inputText = ("iwanttoknowrelatedtoAdvancejava").toLowerCase().replaceAll("\\s", "");
String match = "java";
List keywordsList = new ArrayList<>();//where keywordsList{advance,core,programming} -> keywordlist fetch
// from database
Enumeration e = Collections.enumeration(keywordsList);
int size = keywordsList.size();
while (e.hasMoreElements()) {
for (int i = 0; i < size; i++) {
String s1 = (String) keywordsList.get(i);
if (inputText.contains(s1) && inputText.contains(match)) {
System.out.println("Yes we providing " + s1);
} else if (!inputText.contains(s1) && inputText.contains(match)) {
System.out.println("Yes we are working on java");
}
}
break;
}
Thanks
you can simply do this by using pattern and matcher classes
Pattern p = Pattern.compile("java");
Matcher m = p.matcher("Print this");
m.find();
If you want to find multiple matches in a line, you can call find() and group() repeatedly to extract them all.
Here's how you can achieve what you seek using pattern matching.
In the first example I have taken your input text as it is. This only improves your algorithm which has O(n^2) performance.
String inputText = ("iwanttoknowrelatedtoAdvancejava").toLowerCase().replaceAll("\\s", "");
String match = "java";
List<String> keywordsList = Arrays.asList("advance", "core", "programming");
for (String keyword : keywordsList) {
Pattern p = Pattern.compile(keyword.concat(match));
Matcher m = p.matcher(inputText);
//System.out.println(m.find());
if (m.find()) {
System.out.println("Yes we are providing " + keyword.concat(match));
}
}
But we can improve this in to a better implementation. Here's a more generic version of the above implementation. This code doesn't manipulate the input text before matching, rather we provide a more generic regular expression which ignores spaces and matches case insensitive manner.
String inputText = "i want to know related to Advance java";
String match = "java";
List<String> keywordsList = Arrays.asList("advance", "core", "programming");
for (String keyword : keywordsList) {
Pattern p = Pattern.compile(MessageFormat.format("(?i)({0}\\s*{1})", keyword, match));
Pattern p1 = Pattern.compile(MessageFormat.format("(?i)({0})", match));
Matcher m = p.matcher(inputText);
Matcher m1 = p1.matcher(inputText);
//System.out.println(m.find());
if(m.find()) {
System.out.println("Yes we are providing " + keyword.concat(match));
} else if(m1.find()) {
System.out.println("Yes we are working with " + match);
}
}
#sithum - Thanks but it executes both condition of if else in output.Please refer Screen shot which I attached here.
I applied following logic and it works fine. please refer it , Thanks.
String inputText = ("iwanttoknowrelatedtoAdvancejava").toLowerCase().replaceAll("\\s", "");
String match = "java";
List<String> keywordsList = session.createSQLQuery("SELECT QUESTIONARIES_RAISED FROM QUERIES").list(); // Fetch values from database (advance,core,programming)
String uniqueKeyword=null;
String commonKeyword= null;
int size =keywordsList.size();
for(int i=0;i<size;i++){
String s1 = (String) keywordsList.get(i);//get values one by one from list
if(inputText.contains(match)){
if(inputText.contains(s1) && inputText.contains(match)){
Queries q1 = new Queries();
q1.setQuestionariesRaised(s1); //set matched keyword to getter setter method
keywordsList1=session.createQuery("from Queries sentence where questionariesRaised='"+q1.getQuestionariesRaised()+"'").list(); // based on matched keyword fetch according to matched keyword sentence which stored in database
for(Queries ob : keywordsList1){
uniqueKeyword= ob.getSentence().toString();// Store fetched sentence to on string variable
}
break;
}else {
commonKeyword= "java only";
}
}
}}
if(uniqueKeyword!= null){
System.out.println("Yes we providing......................" + uniqueKeyword);
}else if(commonKeyword!= null){
System.out.println("Yes we providing " + commonKeyword);
}else{
}

How do I extract only right hand side and left hand side values of "=" operator from a line in text file?

Like for eg., in “int bot = 235;” from a line in text file, I want to extract only “bot” and “235” and store it in a HashMap in Java.
You could use regexp:
String detail = "int bot = 235";
String pattern = "(\\w+) = (\\w+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(detail);
HashMap<String, String> result = new HashMap<>();
while (m.find()) {
result.put(m.group(1), m.group(2));
}
System.out.println(result);
gives
{bot=235}
You can use the string function split, like this:
String[] s = string.split("=");
String s1 = string[0]; // "int bot "
String s2 = parts[1]; // " 235;"

Java Split method strings into method name and argument

I am writing a small programming language for a game I am making, this language will be for allowing users to define their own spells for the wizard entity outside the internal game code. I have the language written down, but I'm not entirely sure how to change a string like
setSpellName("Fireball")
setSplashDamage(32,5)
into an array which would have the method name and the arguments after it, like
{"setSpellName","Fireball"}
{"setSplashDamage","32","5"}
How could I do this using java's String.split or string regex's?
Thanks in advance.
Since you're only interested in the function name and parameters I'd suggest scanning up to the first instance of ( and then to the last ) for the params, as so.
String input = "setSpellName(\"Fireball\")";
String functionName = input.substring(0, input.indexOf('('));
String[] params = input.substring(input.indexOf(')'), input.length - 1).split(",");
To capture the String
setSpellName("Fireball")
Do something like this:
String[] line = argument.split("(");
Gets you "setSpellName" at line[0] and "Fireball") at line[1]
Get rid of the last parentheses like this
line[1].replaceAll(")", " ").trim();
Build your JSON with the two "cleaned" Strings.
There's probably a better way with Regex, but this is the quick and dirty way.
With String.indexOf() and String.substring(), you can parse out the function and parameters. Once you parse them out, apply the quotes are around each of them. Then combine them all back together delimited by commas and wrapped in curly braces.
public static void main(String[] args) throws Exception {
List<String> commands = new ArrayList() {{
add("setSpellName(\"Fireball\")");
add("setSplashDamage(32,5)");
}};
for (String command : commands) {
int openParen = command.indexOf("(");
String function = String.format("\"%s\"", command.substring(0, openParen));
String[] parameters = command.substring(openParen + 1, command.indexOf(")")).split(",");
for (int i = 0; i < parameters.length; i++) {
// Surround parameter with double quotes
if (!parameters[i].startsWith("\"")) {
parameters[i] = String.format("\"%s\"", parameters[i]);
}
}
String combine = String.format("{%s,%s}", function, String.join(",", parameters));
System.out.println(combine);
}
}
Results:
{"setSpellName","Fireball"}
{"setSplashDamage","32","5"}
This is a solution using regex, use this Regex "([\\w]+)\\(\"?([\\w]+)\"?\\)":
String input = "setSpellName(\"Fireball\")";
String pattern = "([\\w]+)\\(\"?([\\w]+)\"?\\)";
Pattern r = Pattern.compile(pattern);
String[] matches;
Matcher m = r.matcher(input);
if (m.find()) {
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
String[] params = m.group(2).split(",");
if (params.length > 1) {
matches = new String[params.length + 1];
matches[0] = m.group(1);
System.out.println(params.length);
for (int i = 0; i < params.length; i++) {
matches[i + 1] = params[i];
}
System.out.println(String.join(" :: ", matches));
} else {
matches = new String[2];
matches[0] = m.group(1);
matches[1] = m.group(2);
System.out.println(String.join(", ", matches));
}
}
([\\w]+) is the first group to get the function name.
\\(\"?([\\w]+)\"?\\) is the second group to get the parameters.
This is a Working DEMO.

Best way to split a string containing question marks and equals

Having an issue where I have a java string:
String aString="name==p==?header=hello?aname=?????lname=lastname";
I need to split on question marks followed by equals.
The result should be key/value pairs:
name = "=p=="
header = "hello"
aname = "????"
lname = "lastname"
The problem is aname and lname become:
name = ""
lname = "????lname=lastname"
My code simply splits by doing aString.split("\\?",2)
which will return 2 strings.One contains a key/value pair and the second string contains
the rest of the string. If I find a question mark in the string, I recurse on the second string to further break it down.
private String split(String aString)
{
System.out.println("Split: " + aString);
String[] vals = aString.split("\\?",2);
System.out.println(" - Found: " + vals.length);
for ( int c = 0;c<vals.length;c++ )
{
System.out.println(" - "+ c + "| String: [" + vals[c] + "]" );
if(vals[c].indexOf("?") > 0 )
{
split(vals[c]);
}
}
return ""; // For now return nothing...
}
Any ideas how I could allow a name of ?
Disclaimer: Yes , My Regex skills are very low, so I don't know if this could be done via a regex expression.
You can let regex do all the heavy lifting, first splitting your string up into pairs:
String[] pairs = aString.split("\\?(?!\\?)");
That regex means "a ? not followed by a ?", which gives:
[name==p==, header=hello, aname=????, lname=lastname]
To then also split the results into name/value, split only the first "=":
String[] split = pair.split("=", 2); // max 2 parts
Putting it all together:
String aString = "name==p==?header=hello?aname=?????lname=lastname";
for (String pair : aString.split("\\?(?!\\?)")) {
String[] split = pair.split("=", 2);
System.out.println(split[0] + " is " + split[1]);
}
Output:
name is =p==
header is hello
aname is ????
lname is lastname
You can try like this
String[] vals = "Hello??Man?HowAreYou????".split("\\?+");
System.out.println(vals[0]+vals[1]+vals[2]);
OUTPUT
HelloManHowAreYou
But as aname=????? you want to get you can replace the
????? Five Question Marks with Other Symbol and replace back to ????? after split
String processed="Hello????Good? ? ....???".replace("????","*");
OUTPUT
Hello*Good? ? ....???
And than use split for ?
Here the code, you are looking .
Implemented using the Split and HashMap.
Tested and Executed.
import java.util.HashMap;
import java.util.Map;
public class Sample {
public static void main(String[] args) {
// TODO Auto-generated method stub
// String[] vals = "Hello??Man?HowAreYou????".split("\\?+");
// System.out.println(vals[0]+vals[1]+vals[2]);
String query="name==p==?header=hello?aname=?????lname=lastname";
String[] params = query.split("\\?");
Map<String, String> map = new HashMap<String, String>();
for (String param : params)
{
String name = param.split("=")[0];
String value = param.substring(name.length(),param.length());
map.put(name, value);
System.out.println(name);
if(name.equals("")){
value+="?";
}
System.out.println(value.replaceAll(" ", ""));
}
}
}
I assume you are parsing URLs. The correct way would be to encode all special characters like ?, & and = which are values or names.
Better Solution: Encoding characters:
String name = "=p==";
String aname = "aname=????";
String lname = "lastname";
String url = "name=" + URLEncoder.encode(name, "UTF-8") +
"?aname=" + URLEncoder.encode(aname, "UTF-8") +
"?lname=" + URLEncoder.encode(lname, "UTF-8");
After that you have something like this:
name==p==?aname=?????lname=lastname
This can be splitted and decoded easily.
Other Solution: Bad input parsing:
If you insist, this works also. You can use a regex:
Pattern pattern = Pattern.compile("(\\w+?)=(\\S+?\\?+)");
Matcher m = pattern.matcher(query + "?");
while (m.find()) {
String key = m.group(1);
String value = m.group(2);
value = value.substring(0, value.length() - 1);
System.out.println(key + " = " +value);
}

How to replace a word within a square bracket based a certain condition

I've a tricky condition which does not seem to work. For a given string, "Hi [HandleKey], you have [Action]", and a map which contains, map<"HandleKey","Peter"> I want to replace the square bracket and the word within if the key is found in the map. In this case, the map does not contain the key Action. The string should return "Hi Peter, you have [Action]".
Here is the code that I'm working on:
private String messageFormatter(String tMessage, Map<String, String> messageMap)
{
String formattedMsg = null;
Set<String> keyset = messageMap.keySet();
Iterator<String> keySetItr = keyset.iterator();
String msgkey = null;
boolean isFormatted = false;
while (keySetItr.hasNext())
{
msgkey = keySetItr.next();
if(t.contains(msgkey))
{
if(!isFormatted)
{
formattedMsg = tMessage.replaceAll("\\[", "").replaceAll("\\]", "");
formattedMsg = formattedMsg.replaceAll(msgkey, messageMap.get(msgkey));
isFormatted= true;
}else
{
formattedMsg = formattedMsg.replaceAll(msgkey, messageMap.get(msgkey));;
}
}else
{
formattedMsg=tMessage;
}
}
return formattedMsg;
}
The last else part is not right. Can anyone please help me with this. This code works fine for all the cases except when a matching key is not found in the map
is this idea ok for you?
instead of applying regex or extracting the stuff between [..], you could do some trick on your map side. e.g.
String s = "Hi [HandleKey], you have [Action]";
for(String k: yourMap.keySet()){
s=s.replaceAll("\\["+k+"\\]",yourMap.get(k));
}
You can do this with regex, here is a complete example code
public static void main(String[] args) {
String str = "Hi [HandleKey], you have [Action] ";
Hashtable<String, String> table = new Hashtable<String, String>();
table.put("HandleKey", "Peter");
Pattern pattern = Pattern.compile("\\[(\\w+)\\]");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
String key = matcher.group(1);
if (table.containsKey(key)) {
str = str.replaceFirst("\\[" + key + "\\]", table.get(key));
}
}
System.out.println(str);
}
Output:
Hi Peter, you have [Action]
Note that this is more efficient than looping over the Map if the map size is already large or growing.
To handle when key not in map with minimal changes to what you have above try
formattedMsg.replaceAll(msgkey,
(messageMap.containsKey(msgKey) ? messageMap.get(msgkey) : "[" + msgKey + "]"));
but looking again I can see that you're iterating the set of keys from the messageMap so the issue of a key not appearing in the map doesn't arise?
There's also a reference to if(t.contains(msgKey))... but not sure what t is
if you want the text to contain the formatted [msgKey] when its no found then replacing all "[" & "]" seems the wrong way to start if you want to put them back in in some cases.
I'd look at #iTech's suggestion and get regex doing more for you

Categories