Just for completeness since escaping problem appeared in your question description: \
is special in String literals (in "..."
part). Thanks to it we are able to write many characters which are normally not allowed in String like line separators. With \
we can write them as \r
and \n
(or via many other forms: hexadecimal index \uXXXX
, octal index \OOO
).
But because it is special we also need a way to write \
symbol itself. So to not provide another special character which will allow us to create \
literal we are using another \
to escape it like "\\"
. For instance"\r\n\\"
literal represents 3 characters: carriage return, line feed and \
.
That is why to create string literal representing \d
so we could pass it to regex engine, we need to write it as "\\d"
.
Now back to main part of answer.
[..]
is single character class. So it can match single character in described set. So:
since (..)
is used to group series of characters which is not possible inside [..]
(
and )
looses its meaning there making [(\r\n)\n]
represent single (
or \r
or \n
or )
(notice that \r
and \n
represent single characters representing line break. Also another \n
is redundant)
since \R
beside single \r
or \n
(and few others) can also represents \r\n
sequence, it can't be used inside [..]
since character set may match only single character.
If you use \R
inside [..]
you will get PatternSyntaxException: Illegal/unsupported escape sequence
exception. Java usually allows to add \\
before any character inside character class to:
- to represent predefined character classes:
\\d
\\w
but also in cases where it doesn't change anything like:
\\r
\\n
\\t
where it simply represents same characters as String literals "\r"
"\n"
"\t"
- or before characters which doesn't have any special meaning so we don't really need to escape them
\\x
\\y
\\h
But it will not allow you to try escaping characters which have special meaning outside [...]
and are not guaranteed to represent single characters like \R
or \b
(word boundaries since it doesn't represent character, but place before/after word.
What you can do is use \R
instead of [(\r\n)\n]
(but don't forget to also escape its \
part in String like you did for \d
). You can also remove most outer (...)
pair since entire match is already stored in group 0, so you don't need to add another group for that purpose.
One of simplest ways to rewrite your regex would be:
String regex = "@(\\d+)\\R([01]{"+width+"}\\R){"+height+"}";
But since you may not want to include last line separator feel free to make last \R
optional with ?
quantifier and reluctant by adding another ?
after it like
String regex = "@(\\d+)\\R([01]{"+width+"}\\R??){"+height+"}";
DEMO