I am currently trying to learn how to use regular expressions so please bear with my simple question. For example, say I have an input file containing a bunch of links separ
Works for me:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Foo {
public static void main(String args[]) {
Pattern p = Pattern.compile(".*www.*\\s.*Pig.*");
String s = "www.foo.com/Archives/monkeys.htm\n"
+ "Description of Monkey's website.\n"
+ "\n"
+ "www.foo.com/Archives/pigs.txt\n"
+ "Description of Pig's website.\n"
+ "\n"
+ "www.foo.com/Archives/kitty.txt\n"
+ "Description of Kitty's website.\n"
+ "\n"
+ "www.foo.com/Archives/apple.htm\n"
+ "Description of Apple's website.\n";
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());
} else {
System.out.println("ERR: no match");
}
}
}
Perhaps the problem was with the way you were using the Pattern and Matcher objects?
For future reference, one can also use the Pattern.DOTALL flag for "." to match even \r or \n.
Example:
Say the we are parsing a single string of http header lines like this (each line ended with \r\n)
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: SAMEORIGIN
Location: http://localhost:8080/blah.htm
Content-Length: 0
This pattern:
final static Pattern PATTERN_LOCATION = Pattern.compile(".*?Location\\: (.*?)\\r.*?", Pattern.DOTALL);
Can parse the location value using "matcher.group(1)".
The "." in the above pattern will match \r and \n, so the above pattern can actually parse the 'Location' from the http header lines, where there might be other headers before or after the target line (not that this is a recommended way to parse http headers).
Also, you can use "?s" inside the pattern to achieve the same effect.
If you are doing this, you might be better off using Matcher.find().
This version matches newlines that may be either Windows (\r\n) or Unix (\n)
Pattern p = Pattern.compile("(www.*)((\r\n)|(\n))(.*Pig.*)");
String s = "www.foo.com/Archives/monkeys.htm\n"
+ "Description of Monkey's website.\n"
+ "\r\n"
+ "www.foo.com/Archives/pigs.txt\r\n"
+ "Description of Pig's website.\n"
+ "\n"
+ "www.foo.com/Archives/kitty.txt\n"
+ "Description of Kitty's website.\n"
+ "\n"
+ "www.foo.com/Archives/apple.htm\n"
+ "Description of Apple's website.\n";
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println("found: "+m.group());
System.out.println("website: "+m.group(1));
System.out.println("description: "+m.group(5));
}
System.out.println("done");
String str="I am a "+"\n Man of Peace"+"\t"+" .";
str=str.replaceAll("[\\s|\\t|\\r\\n]+"," ").trim();
System.out.println(str);
This above example works for tabSpaces, newLines, and normal spaces.
And I have used the trim method of java.lang.String
to remove all the additional spaces in 'str'. I hope this helps you and other amazing people here.
The lines are probably separated by \r\n
in your file. Both \r
(carriage return) and \n
(linefeed) are considered line-separator characters in Java regexes, and the .
metacharacter won't match either of them. \s
will match those characters, so it consumes the \r
, but that leaves .*
to match the \n
, which fails. Your tester probably used just \n
to separate the lines, which was consumed by \s
.
If I'm right, changing the \s
to \s+
or [\r\n]+
should get it to work. That's probably all you need to do in this case, but sometimes you have to match exactly one line separator, or at least keep track of how many you're matching. In that case you need a regex that matches exactly one of any of the three most common line separator types: \r\n
(Windows/DOS), \n
(Unix/Linus/OSX) and \r
(older Macs). Either of these will do:
\r\n|[\r\n]
\r\n|\n|\r
Update: As of Java 8 we have another option, \R. It matches any line separator, including not just \r\n
, but several others as defined by the Unicode standard. It's equivalent to this:
\r\n|[\n\x0B\x0C\r\u0085\u2028\u2029]
Here's how you might use it:
(?im)^.*www.*\R.*Pig.*$
The i
option makes it case-insensitive, and the m
puts it in multiline mode, allowing ^
and $
to match at line boundaries.
try this
([^\r]+\r[^\r])+