If you truly want to replicate grep
in Java, you have quite a task ahead of you; for instance, consider the following invocations:
grep something somefile
echo sometext | grep something
grep -x something somefile
grep -Fx something somefile
A lot of options there.
Now, let us tackle the fundamentals.
The first problem is that the .matches()
method, of either String
or Matcher
, is a misnomer. By definition, a regex matches an input if it can recognize any text within the input... Unfortunately this is not how the Java API defines the .matches()
method. Java's .matches()
returns true if and only if the whole input matches the regular expression.
As such, this is not what you should use. Since you use a Matcher
, you want to use .find()
instead.
The second problem is the line by line matching; regexes in general don't care about lines; it just happens that some characters are present which define this notion. Again, regexes do not care.
Regexes do not care, however this notion is important enough that Java has classes allowing to separate a character stream into "lines", by splitting against the necessary characters... So here is how you would replicate grep
by reading from stdin, assuming the default encoding (code written for Java 8+):
public static void main(final String... args)
{
if (args.length == 0)
throw new IllegalArgumentException("missing pattern as an argument");
final Pattern pattern = Pattern.compile(args[0]);
final Charset cs = Charset.defaultCharset();
final CharsetDecoder decoder = cs.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT);
try (
final Reader r = new InputStreamReader(System.in, decoder);
final BufferedReader reader = new BufferedReader(r);
) {
String line;
while ((line = reader.readLine()) != null)
if (pattern.matcher(line).find())
System.out.println(line);
}
}