Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm trying to program a Minecraft Bukkit plugin using Java that will find when an IP is placed in the chat, so I'm using regex for it. What I need is regex to find anywhere in the string, a character followed by a period followed by another character, such as 127.0.0.1 being valid, but it also needs to be able to find it with any characters surrounding it such as This IP: 127.0.0.1 is your localhost IP. This is my current code:
Pattern p = Pattern.compile("[a-z1-9]" + "." + "[a-z1-9]");
Matcher matcher = p.matcher(message);
if(matcher.matches()){
player.sendMessage(plugin.prefix + "ยง7You cannot advertise an IP address!");
event.setCancelled(true);
}
This code will only search for something like 127.0 and only that, but as I said above I need it to find any amount of [letter/number].[letter/number] in any string, if that made sense.
What I need is regex to find anywhere in the string, a character followed by a period followed by another character. I need it to find any amount of [letter/number].[letter/number] in any string, if that made sense...
What you can do here is use a word boundary \b to match for these patterns in larger text.
For a simple solution, you can use something like this.
\\b((?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}|(?:[a-z0-9]+(?:-[a-z0-9]+)*\\.)+[a-z]{2,4}))\\b
Example:
import java.util.regex.*;
class rTest {
public static void main (String[] args) {
String in = "Let's match 127.0.0.1 being valid, or this IP: 127.0.0.1 and joinTHIS.server.com or build 1.2";
String re = "\\b((?:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}|(?:[a-z0-9]+(?:-[a-z0-9]+)*\\.)+[a-z]{2,4}))\\b";
Pattern p = Pattern.compile(re, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(in);
while (m.find()) {
System.out.println(m.group(1));
}
}
}
Output
127.0.0.1
127.0.0.1
joinTHIS.server.com
Read please this: link
PADDRESS_PATTERN =
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])";
Try this:
Pattern.compile("(\\d{1,3}\\.){3}\\d{1,3}");
This will simply find any sequence of 4 3-digit numbers separated by periods.
Edit: plsgogame's answer contains a better pattern for finding an IP address (which may only contain numbers between 0 and 255).
Your regex matches any string of length 3 starting and ending with [a-z0-9] because you're not escaping the '.' which stands for any character. Moreover, the set of character in parenthesis should be repeated. For example you could use something like:
[\d]*\.[\d]*\.[\d]*\.[\d]*
which matches one or more digits followed by a period three times and finally one or more digits. This means you'll get a match for any string of the form '123.456.789.101' but also stuff like '122533252.13242351432142.375547547.62463636', so that's not completely helpful.
An improvement, but not perfect, is the following:
[\d][\d][\d]\.[\d][\d][\d]\.[\d][\d][\d]\.[\d][\d][\d]
which will match groups of three digits separated by a dot.
If you want to fast forward to something much more interesting and effective but also more difficult to understand if you are a beginner, you can use the example found on this page, that is:
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
which does exactly what you need.
Moreover, the matches() method tries to match all of the input, not a section of it, so you could add a '.*' at the beginning and end of the regex and run it from java code like this:
Pattern p = Pattern.compile(".*\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b.*");
Matcher matcher = p.matcher(message);
if (matcher.matches()) System.out.println("It's a match");
If you want to find all the IPs you can do instead:
Pattern p = Pattern.compile("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
Matcher matcher = p.matcher(message);
while (matcher.find()) System.out.println("Match: " + matcher.group());
Regexes are wonderful although the learning curve is steep. So good luck learning!
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a few, theoretical ideas, but I don't know the language well. We basically need to make a rudimentary lexical analyzer. I have most of the bits, but here's the context. The straight-forward question is at the end.
I need to read in a line from the console, then see if parts match up with a symbol table, which includes the keywords: "print [variable]", "load [variable]", "mem [variable]", "sqrt" and "stop", as well as mathematical symbols.
It also needs to recognise the variables on their own (such as "c = a + b" as well.)
So...it's not that hard, in theory. You'd check the first character of the string matched up with keywords or variables. If they do, keep looping through that keyword or variable to check if it's the same string, up until you hit a space.
To summarize: How do I check the characters of a read in string to compare to stuff in Java?
I recommend to use Regex for text pattern matching. You receive the text via console as argument, you do so by using the args array of the main-method. Here's a small example:
public final class Parser {
public static void main(final String[] args) {
if (args.length < 1) {
// Error, no input given
}
String input = args[0];
Pattern pattern = Pattern.compile("YOUR REGEX HERE");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
// Input matches the Regex pattern
// Access to capturing groups using matcher.group(int)
// Example: System.out.println(matcher.group(1));
}
}
}
For Regex you can find various explanations on the web and on SO. You can try out your patterns at regex101.
Here's an example pattern which matches "name = name + name":
(.+) = (.+) \+ (.+)
The () creates capturing groups. Using matcher.group(x) for x from 1 to 3 you can access the matched values inside the brackets, i.e. the variables.
Here's the same example online with test input: regex101.com/r/mJ9jI5/1
Fairly easy. However you may need to make the pattern more robust. It may not accept whitespace characters or special characters (for example a +) inside a variable name and so on.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I tried creating a regex which will help me solve the below problem but was not able to:
Example word : mumbai(10)
The regex should check if the word is ending with parenthesis with a value I.e (10) in the above word "Mumbai(10)". And the value should be extracted I.e 10.
If the word is Mum(10)bai then no results should be the output.
You can use the following to match:
\\((\\d+)\\)$
And extract group 1 $1 for the value.
See DEMO
Java code:
String str = "mumbai(10)";
Matcher m = Pattern.compile("\\((\\d+)\\)$").matcher(str);
if (m.find()) {
System.out.println(m.group(1));
}
String string = "mumbai(10)";
Pattern p = Pattern.compile("^.*\\((\\d+)\\)$");
Matcher m = p.matcher(string);
if (m.matches()) {
System.out.println(m.group(1));
}
^ and $ denote the beginning and end respectively. .* just matches anything. The parenthesis need to be escaped, since they represent a group in regular expression, which is being made use of after that. The captured group can then be extracted using m.group(1).
You can try following regex,
\((\d+)\)$
Demo
It uses the concept of group capture
I'm trying to write a Java routine that can parse out dates from a long string, i.e. given the string:
"Please have the report to me by 6/15, because the shipment comes in on 6/18"
The regex would find both 6/15 and 6/18. I've looked on Stack Overflow and elsewhere, and most examples of a date regex simply verify whether a given string is a date or not, rather than finding dates within a larger amount of text. Ideally, I'd want a regex that could identify all of the main ways people numerically write dates i.e 6/15, 6/15/12, 06/15/12, 15/6/12, 15/06/12, although perhaps it would be best to separate these into different regexes for the purpose of cla. I'm new to regexes (I just started learning about them two days ago) and regexes are still a bit cryptic to me, so I'd appreciate a detailed explanation of any regex suggestions.
If you're not bothering with range checking, this suffices:
(\d{1,2})/(\d{1,2})(?:/(\d{4}|\d{2}))?
To check that you can't do 2/29/2001 but can do 2/29/2000, you really want to do it after the regexp has done its job, or you're going to end up in an asylum.
EDIT: Better yet, for isolating the century, and protecting against things like 2/193 (prompted by Alex's question, even though it's a separate issue):
\b(\d{1,2})/(\d{1,2})(?:/(\d{2})?(\d{2}))?\b
You'd get 4 captures in each match: [month, day, century, year], where century and year could be empty.
\d{1,2}/\d{1,2}(?:/(?:\d{2}){1,2})?
Here's the breakdown:
\d{1,2} matches 1 or 1 digits
/ followed by a /
\d{1,2} followed 1 or 2 more digits
(?:/(?:\d{2}){1,2})? followed by an optional slash and 2 or 4 digit year
From the matches, you'll probably want to parse them with Java DateParse instead of trying to put all the validation rules in the regex.
You may want to protect against fractions as well 1/4th
This can be done by appending a negative lookahead to your regex: (?!th|rd|nd) which causes the regex to not match if followed by th, rd, or nd.
What exactly is your question? You should read some guide about regex first.
You need a method that returns every match in the String like this:
p is the regex, text is your text.
private LinkedList<String> matches(String p, String text) {
LinkedList<String> results = new LinkedList<String>();
Pattern pattern = Pattern.compile(p);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
results.add(matcher.group());
}
return results;
}
You can separate each date-pattern with |
If you put a part of your regex into braces (...), this part is treated as a "group".
So you can extract single numbers out of the matching string (if you want to).
I am working in Java to read a string of over 100000 characters.
I have a list of keywords, that I search the string for, and if the string is present I call a function which does some internal processing.
The kind of keyword I have is "face", for example - I wish to get all the patterns where I have matches for "faces" not "facebook". I can accept a space character behind the face in the string so if in a string I have a match like " face" or " faces" or "face " or " faces" i can accept that too. However I can not accept "duckface" or "duckface " etc.
I have written the regex
Pattern p = Pattern.compile("\\s+"+keyword+"s\\s+|\\s+");
where keyword is my list of keywords, but I am not getting the desired results. Can you read my description and please suggest what might be issue and how I can fix it?
Also if a pointer to a really good regex for Java page is shared I would appreciate that as well.
Thank you Contributers ..
Edit
The reason I know it is not working is I have used the following code:
Pattern p = Pattern.compile("\\s+"+keyword+"s\\s+|\\s+");
Matcher m = p.matcher(myInputDataSting);
if(m.find())
{
System.out.println("Its a Match: "+m.group());
}
This returns a blank string...
If keyword is "face", then your current regex is
\s+faces\s+|\s+
which matches either one or more whitespace characters, followed by faces, followed by one or more whitespace characters, or one or more whitespace characters. (The pipe | has very low precedence.)
What you really want is
\bfaces?\b
which matches a word boundary, followed by face, optionally followed by s, followed by a word boundary.
So, you can write:
Pattern p = Pattern.compile("\\b"+keyword+"s?\\b");
(though obviously this will only work for words like face that form their plurals by simply adding s).
You can find a comprehensive listing of Java's regular-expression support at http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html, but it's not much of a tutorial. For that, I'd recommend just Googling "regular expression tutorial", and finding one that suits you. (It doesn't have to be Java-specific: most of the tutorials you'll find are for flavors of regular-expression that are very similar to Java's.)
You should use
Pattern p = Pattern.compile("\b"+keyword+"s?\b");
, where keyword is not plural. \\b means that keyword must be as a complete word in searched string. s? means that keyword's value may end with s.
If you are not familar enough with regular expressions I recommend reading http://docs.oracle.com/javase/tutorial/essential/regex/index.html, because there are examples and explanations.
I am looking for a pattern to match this "LA5#10.232.140.133#Po6" and one more "LA5#10.232.140.133#Port-channel7" expression in Java using regular expression.
Like we have \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} for IP address validation.
Can we have the pattern like below? Please suggest--
[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#Po\d[1-9]
[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#Port-channel\d[1-9]
Thanks in advance.
==============================
In my program i have,
import java.util.regex.*;
class ptternmatch {
public static void main(String [] args) {
Pattern p = Pattern.compile("\\w\\w\\w#\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}#*");
Matcher m = p.matcher("LA5#10.232.140.133#Port-channel7");
boolean b = false;
System.out.println("Pattern is " + m.pattern());
while(b = m.find()) {
System.out.println(m.start() + " " + m.group());
}
}
}
But i am getting compilation error with the pattern.--> Invalid escape sequence
The sequence will be like a ->a 3 character word of digit n letter#ipaddress#some text..
Well, if you want to validate the IP address, then you need something a little bit more involved than \d{1,3}. Also, keep in mind that for Java string literals, you need to escape the \ with \\ so you end up with a single backslash in the actual regex to escape a character such as a period (.).
Assuming the LA5# bit is static and that you're fine with either Po or Port-channel followed by a digit on the end, then you probably need a regex along these lines:
LA5#(((2((5[0-5])|([0-4][0-9])))|(1[0-9]{2})|([1-9][0-9]?)\\.){3}(2(5[0-5]|[0-4][0-9]))|(1[0-9]{2})|([1-9][0-9]?)#Po(rt-channel)?[1-9]
(Bracketing may be wonky, my apologies)
You can do something like matcher.find() and, if it is true, the groups to capture the information. Take a look a the tutorial here:
http://download.oracle.com/javase/tutorial/essential/regex/
You would need to wrap the necessary parts int parentheses - e.g. (\d{1,3}). If you wrap all 4, you will have 4 groups to access.
Also, take a look at this tutorial
http://www.javaworld.com/javaworld/jw-07-2001/jw-0713-regex.html?page=3
It's a very good tutorial, I think this one would explain most of your questions.
To match the second of your strings:
LA5#10.232.140.133#Port-channel7
you can use something like:
\w{2}\d#\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}#[a-zA-Z\-]+\d
This depends on what you want to do, so the regex might change.