28

The raw data is:

auser1 home1b
auser2 home2b
auser3 home3b

I want to match a line, but it doesn't work using ^(.*?)$

However, I can use a(.*?)b to match user1 home1.

How can I match auser1 home1b

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
performanceuser
  • 2,793
  • 5
  • 34
  • 44

2 Answers2

72

By default, ^ and $ match the start- and end-of-input respectively. You'll need to enable MULTI-LINE mode with (?m), which causes ^ and $ to match the start- and end-of-line:

(?m)^.*$

The demo:

import java.util.regex.*;

public class Main {
    public static void main(String[] args) throws Exception {

        String text = "auser1 home1b\n" +
                "auser2 home2b\n" +
                "auser3 home3b";

        Matcher m = Pattern.compile("(?m)^.*$").matcher(text);

        while (m.find()) {
            System.out.println("line = " + m.group());
        }
    }
}

produces the following output:

line = auser1 home1b
line = auser2 home2b
line = auser3 home3b

EDIT I

The fact that ^.*$ didn't match anything is because the . by default doesn't match \r and \n. If you enable DOT-ALL with (?s), causing the . to match those as well, you'll see the entire input string being matched:

(?s)^.*$

EDIT II

In this case, you mind as well drop the ^ and $ and simply look for the pattern .*. Since . will not match \n, you'll end up with the same matches when looking for (?m)^.*$, as @Kobi rightfully mentioned in the comments.

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • Can you tell me why ^(.*?)$ match nothing? – performanceuser May 26 '11 at 18:31
  • 2
    Another sneaky option is matching for `.*`. – Kobi May 26 '11 at 18:31
  • 1
    @performanceuser Also note that MULTI-LINE mode `(?m)`, which affects the `^` and `$` anchors, is independent from SINGLE-LINE mode `(?s)`, which affects the `.` operator. You can sensibly combine MULTI-LINE and SINGLE-LINE mode, but that is not what you want here. – Christian Semrau May 26 '11 at 18:34
  • @performanceuser By default, MULTI-LINE mode is disabled, so `^` and `$` only match the start and end of the input string, not after and before each newline within the input string. And SINGLE-LINE mode is disabled, so `.` does not match newline characters. That's why `^.*$` does not match an input string with newline characters. – Christian Semrau May 26 '11 at 18:35
  • @performanceuser, see **EDIT I** why `^(.*?)$` didn't match anything in your case. – Bart Kiers May 26 '11 at 18:37
  • Technically, `^` and `$` match the start/end of a **line**, and `\A`, `\a`, `\Z`, and `\z` are for start/end of **input**. See [here](https://docs.oracle.com/javase/tutorial/essential/regex/bounds.html). – EntangledLoops Feb 19 '16 at 00:31
  • 1
    @EntangledLoops I find the docs are not too clear about that. They are only start- and end-of-line chars when multi-line-mode is enabled (which by default, it isn't). So just saying they're start- and end-of-line chars is IMHO misleading. – Bart Kiers Feb 19 '16 at 09:10
  • @BartKiers Yeah, I was being a bit pedantic and you're correct, the docs aren't very clear at all. The examples even use unexplained matching patterns and you're supposed to somehow appreciate the output. They should really fix that. – EntangledLoops Feb 19 '16 at 13:45
3

we can also use the flag MULTILINE,

 Matcher m = Pattern.compile("^.*$",Pattern.MULTILINE).matcher(text);

This will enable the multiline mode which will gave you the expected result.

Nambi_0915
  • 1,091
  • 8
  • 21