First, i'm read the documentation as follow
http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html
And i want find any punctuation character EXCEPT #',& but i don't quite understand.
Here is :
public static void main( String[] args )
{
// String to be scanned to find the pattern.
String value = "#`~!#$%^";
String pattern = "\\p{Punct}[^#',&]";
// Create a Pattern object
Pattern r = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
// Now create matcher object.
Matcher m = r.matcher(value);
if (m.find()) {
System.out.println("Found value: " + m.groupCount());
} else {
System.out.println("NO MATCH");
}
}
Result is NO MATCH.
Is there any mismatch ?
Thanks
MRizq
You're matching two characters, not one. Using a (negative) lookahead should solve the task:
(?![#',&])\\p{Punct}
You may use character subtraction here:
String pat = "[\\p{Punct}&&[^#',&]]";
The whole pattern represents a character class, [...], that contains a \p{Punct} POSIX character class, the && intersection operator and [^...] negated character class.
A Unicode modifier might be necessary if you plan to also match all Unicode punctuation:
String pat = "(?U)[\\p{Punct}&&[^#',&]]";
^^^^
The pattern matches any punctuation (with \p{Punct}) except #, ', , and &.
If you need to exclude more characters, add them to the negated character class. Just remember to always escape -, \, ^, [ and ] inside a Java regex character class/set. E.g. adding a backslash and - might look like "[\\p{Punct}&&[^#',&\\\\-]]" or "[\\p{Punct}&&[^#',&\\-\\\\]]".
Java demo:
String value = "#`~!#$%^,";
String pattern = "(?U)[\\p{Punct}&&[^#',&]]";
Pattern r = Pattern.compile(pattern); // Create a Pattern object
Matcher m = r.matcher(value); // Now create matcher object.
while (m.find()) {
System.out.println("Found value: " + m.group());
}
Output:
Found value: #
Found value: !
Found value: #
Found value: %
Found value: ,
Related
I am trying to get all the matching groups in my string.
My regular expression is "(?<!')/|/(?!')". I am trying to split the string using regular expression pattern and matcher. string needs to be split by using /, but '/'(surrounded by ') this needs to be skipped. for example "One/Two/Three'/'3/Four" needs to be split as ["One", "Two", "Three'/'3", "Four"] but not using .split method.
I am currently the below
// String to be scanned to find the pattern.
String line = "Test1/Test2/Tt";
String pattern = "(?<!')/|/(?!')";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.matches()) {
System.out.println("Found value: " + m.group(0) );
} else {
System.out.println("NO MATCH");
}
But it always saying "NO MATCH". where i am doing wrong? and how to fix that?
Thanks in advance
To get the matches without using split, you might use
[^'/]+(?:'/'[^'/]*)*
Explanation
[^'/]+ Match 1+ times any char except ' or /
(?: Non capture group
'/'[^'/]* Match '/' followed by optionally matching any char except ' or /
)* Close group and optionally repeat it
Regex demo | Java demo
String regex = "[^'/]+(?:'/'[^'/]*)*";
String string = "One/Two/Three'/'3/Four";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
Output
One
Two
Three'/'3
Four
Edit
If you do not want to split don't you might also use a pattern to not match / but only when surrounded by single quotes
[^/]+(?:(?<=')/(?=')[^/]*)*
Regex demo
Try this.
String line = "One/Two/Three'/'3/Four";
Pattern pattern = Pattern.compile("('/'|[^/])+");
Matcher m = pattern.matcher(line);
while (m.find())
System.out.println(m.group());
output:
One
Two
Three'/'3
Four
Here is simple pattern matching all desired /, so you can split by them:
(?<=[^'])\/(?=')|(?<=')\/(?=[^'])|(?<=[^'])\/(?=[^'])
The logic is as follows: we have 4 cases:
/ is sorrounded by ', i.e. `'/'
/ is preceeded by ', i.e. '/
/ is followed by ', i.e. /'
/ is sorrounded by characters other than '
You want only exclude 1. case. So we need to write regex for three cases, so I have written three similair regexes and used alternation.
Explanation of the first part (other two are analogical):
(?<=[^']) - positiva lookbehind, assert what preceeds is differnt frim ' (negated character class [^']
\/ - match / literally
(?=') - positiva lookahead, assert what follows is '\
Demo with some more edge cases
Try something like this:
String line = "One/Two/Three'/'3/Four";
String pattern = "([^/]+'/'\d)|[^/]+";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
boolean found = false;
while(m.find()) {
System.out.println("Found value: " + m.group() );
found = true;
}
if(!found) {
System.out.println("NO MATCH");
}
Output:
Found value: One
Found value: Two
Found value: Three'/'3
Found value: Four
I am very stuck. I use this format to read a player's name in a string, like so:
"[PLAYER_yourname]"
I have tried for a few hours and can't figure out how to read only the part after the '_' and before the ']' to get there name.
Could I have some help? I played around with sub strings, splitting, some regex and no luck. Thanks! :)
BTW: This question is different, if I split by _ I don't know how to stop at the second bracket, as I have other string lines past the second bracket. Thanks!
You can do:
String s = "[PLAYER_yourname]";
String name = s.substring(s.indexOf("_") + 1, s.lastIndexOf("]"));
You can use a substring. int x = str.indexOf('_') gives you the character where the '_' is found and int y = str.lastIndexOF(']') gives you the character where the ']' is found. Then you can do str.substring(x + 1, y) and that will give you the string from after the symbol until the end of the word, not including the closing bracket.
Using the regex matcher functions you could do:
String s = "[PLAYER_yourname]";
String p = "\\[[A-Z]+_(.+)\\]";
Pattern r = Pattern.compile(p);
Matcher m = r.matcher(s);
if (m.find( ))
System.out.println(m.group(1));
Result:
yourname
Explanation:
\[ matches the character [ literally
[A-Z]+ match a single character (case sensitive + between one and unlimited times)
_ matches the character _ literally
1st Capturing group (.+) matches any character (except newline)
\] matches the character ] literally
This solution uses Java regex
String player = "[PLAYER_yourname]";
Pattern PLAYER_PATTERN = Pattern.compile("^\\[PLAYER_(.*?)]$");
Matcher matcher = PLAYER_PATTERN.matcher(player);
if (matcher.matches()) {
System.out.println( matcher.group(1) );
}
// prints yourname
see DEMO
You can do like this -
public static void main(String[] args) throws InterruptedException {
String s = "[PLAYER_yourname]";
System.out.println(s.split("[_\\]]")[1]);
}
output: yourname
Try:
Pattern pattern = Pattern.compile(".*?_([^\\]]+)");
Matcher m = pattern.matcher("[PLAYER_yourname]");
if (m.matches()) {
String name = m.group(1);
// name = "yourname"
}
I am trying to identify any special characters ('?', '.', ',') at the end of a string in java. Here is what I wrote:
public static void main(String[] args) {
Pattern pattern = Pattern.compile("{.,?}$");
Matcher matcher = pattern.matcher("Sure?");
System.out.println("Input String matches regex - "+matcher.matches());
}
This returns a false when it's expected to be true. Please suggest.
Use "sure?".matches(".*[.,?]").
String#matches(...) anto-anchors the regex with ^ and $, no need to add them manually.
This is your code:
Pattern pattern = Pattern.compile("{.,?}$");
Matcher matcher = pattern.matcher("Sure?");
System.out.println("Input String matches regex - "+matcher.matches());
You have 2 problems:
You're using { and } instead of character class [ and ]
You're using Matcher#matches() instead of Matcher#find. matches method matches the full input line while find performs a search anywhere in the string.
Change your code to:
Pattern pattern = Pattern.compile("[.,?]$");
Matcher matcher = pattern.matcher("Sure?");
System.out.println("Input String matches regex - " + matcher.find());
Try this
Pattern pattern = Pattern.compile(".*[.,?]");
...
I need help with a simple task in java. I have the following sentence:
Where Are You [Employee Name]?
your have a [Shift] shift..
I need to extract the strings that are surrounded by [ and ] signs.
I was thinking of using the split method with " " parameter and then find the single words, but I have a problem using that if the phrase I'm looking for contains: " ". using indexOf might be an option as well, only I don't know what is the indication that I have reached the end of the String.
What is the best way to perform this task?
Any help would be appreciated.
Try with regex \[(.*?)\] to match the words.
\[: escaped [ for literal match as it is a meta char.
(.*?) : match everything in a non-greedy way.
Sample code:
Pattern p = Pattern.compile("\\[(.*?)\\]");
Matcher m = p.matcher("Where Are You [Employee Name]? your have a [Shift] shift.");
while(m.find()) {
System.out.println(m.group());
}
Here you go Java regular expression that extract text between two brackets including white spaces:
import java.util.regex.*;
class Main
{
public static void main(String[] args)
{
String txt="[ Employee Name ]";
String re1=".*?";
String re2="( )";
String re3="((?:[a-z][a-z]+))"; // Word 1
String re4="( )";
String re5="((?:[a-z][a-z]+))"; // Word 2
String re6="( )";
Pattern p = Pattern.compile(re1+re2+re3+re4+re5+re6,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m = p.matcher(txt);
if (m.find())
{
String ws1=m.group(1);
String word1=m.group(2);
String ws2=m.group(3);
String word2=m.group(4);
String ws3=m.group(5);
System.out.print("("+ws1.toString()+")"+"("+word1.toString()+")"+"("+ws2.toString()+")"+"("+word2.toString()+")"+"("+ws3.toString()+")"+"\n");
}
}
}
if you want to ignore white space remove "( )";
This is a Scanner base solution
Scanner sc = new Scanner("Where Are You [Employee Name]? your have a [Shift] shift..");
for (String s; (s = sc.findWithinHorizon("(?<=\\[).*?(?=\\])", 0)) != null;) {
System.out.println(s);
}
output
Employee Name
Shift
Use a StringBuilder (I assume you don't need synchronization).
As you suggested, indexOf() using your square bracket delimiters will give you a starting index and an ending index. use substring(startIndex + 1, endIndex - 1) to get exactly the string you want.
I'm not sure what you meant by the end of the String, but indexOf("[") is the start and indexOf("]") is the end.
That's pretty much the use case for a regular expression.
Try "(\\[[\\w ]*\\])" as your expression.
Pattern p = Pattern.compile("(\\[[\\w ]*\\])");
Matcher m = p.matcher("Where Are You [Employee Name]? your have a [Shift] shift..");
if (m.find()) {
String found = m.group();
}
What does this expression do?
First it defines a group (...)
Then it defines the starting point for that group. \[ matches [ since [ itself is a 'keyword' for regular expressions it has to be masked by \ which is reserved in Java Strings and has to be masked by another \
Then it defines the body of the group [\w ]*... here the regexpression [] are used along with \w (meaning \w, meaning any letter, number or undescore) and a blank, meaning blank. The * means zero or more of the previous group.
Then it defines the endpoint of the group \]
and closes the group )
Regex:
"-[0-9]{0,}"
String:
"-abc"
According to the test here, that should not happen. I assume I'm doing something wrong in my code.
Code:
public static void main(String[] args) {
String s = "-abc";
String regex = "-[0-9]{0,}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
if (matcher.group().length() == 0)
break;
// get the number less the dash
int beginIndex = matcher.start();
int endIndex = matcher.end();
String number = s.substring(beginIndex + 1, endIndex);
s = s.replaceFirst(regex, "negative " + number);
}
System.out.println(s);
}
Some context: The speech synthesis program I use cannot pronounce numbers with a leading negative sign, so it must be replaced with the word "negative".
-[0-9]{0,}
means your sting must have -, then could be 0 or more numbers.
so -abc is 0 number case
you didn't specify ^ and $, so your regex matches foo-bar or lll-0 even abc- as well
{0,} has exactly the same meaning as *. You regexp thus means "a dash that can be followed by digits". -abc contains a dash, so the pattern get found.
-\d+ should suit your needs better (don't forget to escape the backslash for java: -\\d+).
If you want the whole string to match the pattern, anchor your regexp with ^ and $: ^-\d+$.