package com.j;
public class Program {
public static void main(String[] args) {
System.out.println(Puzzel.class.getName().replaceAll(".", "/")
+ ".class");
System.out.println(Program.class.getName());
}
}
in the above program i was expecting a output com/j/Program.class
But it is coming //////.class its y?
In the replacement, . is treated as a regular expression, where . means "any character" and here is replaced with / , so the output becomes
////////////.class
For the expected answer, change the expression to escape the .:
Name.class.getName().replaceAll("\\.", "/") + ".class");
Then the output will be what you expected:
com/j/Puzzel.class
Because . is a special char when it comes to regex. You should escape it with backslash.
replaceAll() takes a regular expression for the matcher. Your code says to replace every character (.) with a /. you need replaceAll("\\.") or maybe replaceAll("\\\\."). I can never remember how many escapes to use offhand.
Related
I have two regular expression extractors.
One for .java files and the other is for .scala files
val JavaFileRegEx =
"""\S*
\s+
//
\s{1}
([^\.java]+)
\.java
""".replaceAll("(\\s)", "").r
val ScalaFileRegEx =
"""\S*
\s+
//
\s{1}
([^\.scala]+)
\.scala
""".replaceAll("(\\s)", "").r
I want to use these extractors above to extract a java file name and a scala file name from the example code below.
val string1 = " // Tester.java"
val string2 = " // Hello.scala"
string1 match {
case JavaFileRegEx(fileName1) => println(" Java file: " + fileName1)
case other => println(other + "--NO_MATCH")
}
string2 match {
case ScalaFileRegEx(fileName2) => println(" Scala file: " + fileName2)
case other => println(other + "--NO_MATCH")
}
I get this output indicating that the .java file matched but the .scala file did not.
Java file: Tester
// Hello.scala--NO_MATCH
How is it that the Java file matched but the .scala file did not?
NOTE
[] denotes character class. It matches only a single character.
[^] denotes match anything except the characters present in the character class.
In your first regex
\S*\s+//\s{1}([^\.java]+)\.java
\S* matches nothing as there is space in starting
\s+ matches the space which is in starting
// matches // literally
\s{1} matches next space
You are using [^\.java] which says match anything except . or j or a or v or a which can be written as [^.jav].
So, the left string now to be tested is
Tester.java
(Un)luckily any character from Tester does not matches . or j or a or v until we encounter a .. So Tester is matched and then java is also matched.
In your second regex
\S*\s+//\s{1}([^\.scala]+)\.scala
\S* matches nothing as there is space in starting
\s+ matches the space which is in starting
// matches // literally
\s{1} matches next space
Now, you are using [^\.scala] which says that match anything except . or s or c or a or l or a which can be written as [^.scla].
You have now
Hello.scala
but (un)luckily Hello here contains l which is not allowed according to character class and the regex fails.
How to correct it?
I will modify only a bit of your regex
\S*\s+//\s{1}([^.]*)\.java
<-->
This says that match anything except .
You can also use \w here instead if [^.]
Regex Demo
\S*\s+//\s{1}([^.]*)\.scala
Regex Demo
There is no need of {1} in \s{1}. You can simply write it as \s and it will match exactly one space like
\S*\s+//\s([^.]*)\.java
I have got example expression :
firstName =:'Mon';lastName =:'Arthur';:or{size >:'20';lastName ^:'H';:and{company |:'lon';:or{company |:'we'}}};lastName =:'aa';:and{length >:'33';:or{color =:'red'};width <:'2'};date <:'2012';:!{source =:'dictionary,locale'}
and regex must match:
:or{size >:'20';lastName ^:'H';:and{company |:'lon';:or{company |:'we'}}}
:and{length >:'33';:or{color =:'red'};width <:'2'}
:!{source =:'dictionary, locale'}
So that regex must match to expression that start with ':[anycharacters]{' and end with '}' and expression between that curly parentheses may also contains inner expression that can match.
I try to wrote something:
https://regex101.com/r/gM3dR9/13
and the return is:
:or{size >:'20';lastName ^:'H';:and{company |:'lon';:or{company |:'we'} - OK
:and{length >:'33';:or{color =:'red'} -MISSING ;width <:'2'}
:!{source =:'dictionary, locale'} -OK
I tried to work out a solution that fits your example and the requirements you wrote, but I'm not sure, if I got it entirely:
(?:;:)(\S+(?:{.*?}(?=[^}]*$|;[^}]*;:)))
This uses a positive lookahead to ensure that the last closing bracket is catched correctly (it has to be followed by the end of the string or another ;:)
If it is possible, that your match is the beginning of the string and therefor not proceeded by ;: you could change the part (?:;:) to (?:^|;:)
Here is the link for Regex101: https://regex101.com/r/dV8uI4/1
Try this regEx
(:or{.*?\};{1,})|(:and{.*\};)|(:!{.*?\};{0,})
I can't guarantee for any other complex case, but it is definitely what you have mentioned as output Except extra ';'
"firstName =:'Mon';lastName =:'Arthur';:or{size >:'20';lastName ^:'H';:and{company |:'lon';:or{company |:'we'}}};lastName =:'aa';:and{length >:'33';:or{color =:'red'};:width <:'2'};date <:'2012';:!{source =:'dictionary,locale'}".match(/(:or{.*?\};{1,})|(:and{.*\};)|(:!{.*?\};{0,})/g)
Output
[":or{size >:'20';lastName ^:'H';:and{company |:'lon';:or{company |:'we'}}};", ":and{length >:'33';:or{color =:'red'};:width <:'2'};", ":!{source =:'dictionary,locale'}"]
Formatted output
[
":or{size >:'20';lastName ^:'H';:and{company |:'lon';:or{company |:'we'}}};",
":and{length >:'33';:or{color =:'red'};:width <:'2'};",
":!{source =:'dictionary,locale'}"
]
tested Here - Java RegEx Tester
If I have this:
thisisgibberish 1234 /hello/world/
more gibberish 43/7 /good/timing/
just onemore 8888 /thanks/mate
what would the regular expression inside the Java String.split() method be to obtain the paths per line?
ie.
[0]: /hello/world/
[1]: /good/timing/
[2]: /thanks/mate
Doing
myString.split("\/[a-zA-Z]")
causes the splits to occur to every /h, /w, /g, /t, and /m.
How would I go about writing a regular expression to split it only once per line while only capturing the paths?
Thanks in advance.
Why split ? I think running a match here is better, try the following expression:
(?<=\s)(/[a-zA-Z/])+
Regex101 Demo
This uses split() :
String[] split = myString.split(myString.substring(0, myString.lastIndexOf(" ")));
OR
myString.split(myString.substring(0, myString.lastIndexOf(" ")))[1]; //works for current inputs
You must first remove the leading junk, then split on the intervening junk:
String[] paths = str.replaceAll("^.*? (?=/[a-zA-Z])", "")
.split("(?m)((?<=[a-zA-Z]/|[a-zA-Z])\\s|^).*? (?=/[a-zA-Z])");
One important point here is the use of (?m), which is a switch that turns on "dot matches newline", which is required to split across the newlines.
Here's some test code:
String str = "thisisgibberish 1234 /hello/world/\nmore gibberish 43/7 /good/timing/\njust onemore 8888 /thanks/mate";
String[] paths = str.replaceAll("^.*? (?=/[a-zA-Z])", "")
.split("(?m)((?<=[a-zA-Z]/|[a-zA-Z])\\s|^).*? (?=/[a-zA-Z])");
System.out.println( Arrays.toString( paths));
Output (achieving requirements):
[/hello/world/, /good/timing/, /thanks/mate]
I am developing an application in which I need to process text files containing emails. I need all the tokens from the text and the following is the definition of token:
Alphanumeric
Case-sensitive (case to be preserved)
'!' and '$' are to be considered as constituent characters. Ex: FREE!!, $50 are tokens
'.' (dot) and ',' comma are to be considered as constituent characters if they occur between numbers. For ex:
192.168.1.1, $24,500
are tokens.
and so on..
Please suggest me some open-source tokenizers for Java which are easy to customize to suit my needs. Will simply using StringTokenizer and regex be enough? I have to perform stopping also and that's why I was looking for an open source tokenizer which will also perform some extra things like stopping, stemming.
A few comments up front:
From StringTokenizer javadoc:
StringTokenizer is a legacy class that is retained for compatibility
reasons although its use is discouraged in new code. It is recommended
that anyone seeking this functionality use the split method of String
or the java.util.regex package instead.
Always use Google first - the first result as of now is JTopas. I did not use it, but it looks it could work for this
As for regex, it really depends on your requirements. Given the above, this might work:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Mkt {
public static void main(String[] args) {
Pattern p = Pattern.compile("([$\\d.,]+)|([\\w\\d!$]+)");
String str = "--- FREE!! $50 192.168.1.1 $24,500";
System.out.println("input: " + str);
Matcher m = p.matcher(str);
while(m.find()) {
System.out.println("token: " + m.group());
}
}
}
Here's a sample run:
$ javac Mkt.java && java Mkt
input: --- FREE!! $50 192.168.1.1 $24,500
token: FREE!!
token: $50
token: 192.168.1.1
token: $24,500
Now, you might need to tweak the regex, for example:
You gave $24,500 as an example. Should this work for $24,500abc or $24,500EUR?
You mentioned 192.168.1.1 should be included. Should it also include 192,168.1,1 (given . and , are to be included)?
and I guess there are other things to consider.
Hope this helps to get you started.
I want to add a '\' character to every string in a list of strings... I m doing something like this but it adds 2 backslashes instead.
feedbackMsgs.add(behaviorName+"\\"+fbCode);
result is like: "abc\\def"
how to make sure a single backslash is added??
I've just run a program with the following -
String s = "test" + "\\" + "test2";
System.out.println(s);
And it prints out the following -
test\test2
Are you sure there is no \ in the behaviourName or fbCode variables?
Looks like either your behaviourName ends with a \ or fbCode starts with one.
Try to Log/print behaviorName fbCode and find it yourself !
System.out.println(behaviorName);
System.out.println(fbCode);