0

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.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Eli
  • 327
  • 4
  • 14
  • 1
    You should read some [regex tutorial](http://www.regular-expressions.info/tutorial.html) or at least try to search [regex for IP](http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address) before asking question. `.` is special character, it means "any character except new line mark" and `[a-z1-9]` would match *one* character in range `a-z` or `1-9` so you would need to add quantifiers. Also if you want to match IPv4 then what `a-z` is doing in your regex? – Pshemo Oct 24 '13 at 21:20
  • @Pshemo Read my comment for plsgogame's answer. – Eli Oct 24 '13 at 21:26
  • If you want to also find hostname like `jointhis.server.com` then you definitely should read answer in question I linked in my previous comment. – Pshemo Oct 24 '13 at 21:30
  • Possible dupplicate: [regular-expression-to-match-hostname-or-ip-address](http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address). – Pshemo Oct 24 '13 at 21:47

4 Answers4

1

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])";
plsgogame
  • 1,334
  • 15
  • 28
  • Only issue is `^` and `$` at the beginning and end that will stop it from finding IP addresses for the OP's application. Other than that, this is a very good answer. – Ben Barkay Oct 24 '13 at 21:20
  • I really like this answer, it mostly works, but I also need it so that it can be found inside a string with that randomly thrown in there somewhere, and for it to work with letters too, because some IPs can use a custom IP such as jointhis.server.com or something – Eli Oct 24 '13 at 21:25
  • 1
    @DonkeyTeeth2013 what you are describing is not an IP address, but a hostname. The regex to find hostnames can be found in the link plsgogame posted in this answer. You should upvote and accept this answer as it actually answers your question correctly and provides working code for it. – Ben Barkay Oct 24 '13 at 21:32
1

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
hwnd
  • 69,796
  • 4
  • 95
  • 132
  • Awesome! I changed the regex a little bit (added a couple .*'s) and it works perfectly for IPs, hostnames, and in any string surrounding it that I tried. Thanks :) – Eli Oct 24 '13 at 22:21
0

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).

Ben Barkay
  • 5,473
  • 2
  • 20
  • 29
0

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!

Giovanni Botta
  • 9,626
  • 5
  • 51
  • 94