String ·
‹ Previous Next ›
⏱ 5 min read Modified: 2026-10-16

Regular Expressions in Java (Regex)

Calling "192.168.0.1".split(".") does not give you four numbers — it returns an empty array of length 0. The reason is that split() takes a regular expression, not plain text, and a dot in a regex means "any character", so the whole string turns into one long delimiter. Learn the regex syntax once, and surprises like this stop costing you an hour of debugging.

Regular expressions in Java (regex) are patterns written in a special language of metacharacters that let you search, validate, replace and split text. The API lives in the java.util.regex package: the Pattern class holds a compiled pattern, and the Matcher class applies it to a particular string. Several String methods also accept a regular expression: matches(), split(), replaceAll() and replaceFirst().

What is a regular expression in Java

A regular expression describes not one specific string but a whole family of strings: "three digits", "a word made of Latin letters", "a file name with an extension". Java applies such a pattern to a text and tells you whether it matches the entire string or just part of it, where exactly the match is, and which fragments were captured by groups.

Say we have this text:

We use the files file1.doc and file2.txt.
It would also be worth looking at file3.img.
Please check the contents of file4.doc as well.

We want to extract every file name: file1.doc, file2.txt, file3.img, file4.doc. This regular expression does the job:

[a-zA-Z0-9]+\.[a-z]{3}

Piece by piece: [a-zA-Z0-9]+ is one or more Latin letters or digits (the file name), \. is a literal dot (without the backslash, the dot would mean "any character"), and [a-z]{3} is exactly three lowercase Latin letters (the extension). The digits in the first set matter: the pattern [a-zA-Z]+\.[a-z]{3} finds none of the names above, because a digit stands right before each dot.

Inside a Java string literal the backslash is doubled, so \. is written as "\\.":

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileNamesExample {
    public static void main(String[] args) {
        String text = "We use the files file1.doc and file2.txt.\n"
                + "It would also be worth looking at file3.img.\n"
                + "Please check the contents of file4.doc as well.";
        Pattern pattern = Pattern.compile("[a-zA-Z0-9]+\\.[a-z]{3}");
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}
// Output:
// file1.doc
// file2.txt
// file3.img
// file4.doc

Two backslashes, not one

Outside Java code, this lesson writes patterns the way the regex engine sees them (\d, \.); inside Java code, with a second backslash ("\\d", "\\."). Writing "\d" in a Java string does not compile: illegal escape character. And to match a literal backslash in the text, a Java string needs four of them: "\\\\".

Pattern and Matcher: how to use regex in Java

To use a regular expression in Java, compile it with Pattern.compile(), then call pattern.matcher(text) to get a Matcher object that searches for matches in that particular string. Neither class has a public constructor: a Pattern is created only through compile(), and a Matcher only through matcher().

Pattern is a compiled, immutable representation of a regular expression. Compilation checks the syntax (an error throws PatternSyntaxException) and builds an internal structure for fast matching, so it pays to create a Pattern once (for example, in a static final field) and reuse it.

Matcher is the "search engine" that keeps the state of matching against one string: the current position, the last match and its groups. For each new string you either create a new Matcher or call reset(newText).

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternMatcherExample {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("[a-z]+");
        Matcher matcher = pattern.matcher("code 2 learn java tutorial");
        while (matcher.find()) {
            System.out.println(matcher.group() + " [" + matcher.start() + ", " + matcher.end() + ")");
        }
    }
}
// Output:
// code [0, 4)
// learn [7, 12)
// java [13, 17)
// tutorial [18, 26)

The pattern [a-z]+ is a run of one or more lowercase Latin letters, so the digit 2 and the spaces never become part of a match. start() returns the index of the first character of the match, and end() the index just after the last one (the same convention as substring()).

Key methods of the Pattern class:

Method What it does Worth knowing
Pattern.compile(regex) Compiles a pattern A syntax error throws PatternSyntaxException
Pattern.compile(regex, flags) Compiles a pattern with flags Combine flags with |, see Pattern flags
pattern.matcher(text) Creates a Matcher for a string Accepts any CharSequence, including a StringBuilder
Pattern.matches(regex, text) Checks that the whole string matches the pattern Compiles the pattern on every call
pattern.split(text) Splits a string around matches splitAsStream() (Java 8) returns a Stream<String>
Pattern.quote(s) Turns a string into a pattern that matches it literally Handy for user input
asPredicate() / asMatchPredicate() Return a Predicate<String> for filtering The first works like find() (Java 8), the second like matches() (Java 11)

Key methods of the Matcher class:

Method What it does Edge case
matches() The pattern matches the entire string "\\d+" on "abc123" — false
lookingAt() The pattern matches the beginning of the string "\\d+" on "123abc" — true
find() Finds the next match anywhere in the string Each call continues from where the previous match ended
group(), group(n), group("name") Text of the match or of a group Before a successful match — IllegalStateException: No match found
start(), end() Start and end (exclusive) index of the match Also require a successful match
groupCount() Number of groups in the pattern Group 0 (the whole match) is not counted
replaceAll(r), replaceFirst(r) Replace all matches or the first one $1 in the replacement refers to a group
results() Stream of all matches, Stream<MatchResult> Java 9+
reset(), reset(text) Resets the search position, optionally switches the string Lets you reuse a Matcher

Since Java 9 you can collect all matches into a list with a single chain of calls using results():

import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;

public class ResultsExample {
    public static void main(String[] args) {
        List<String> numbers = Pattern.compile("\\d+")
                .matcher("a1b22c333")
                .results()
                .map(MatchResult::group)
                .toList();
        System.out.println(numbers);
    }
}
// Output: [1, 22, 333]

Stream.toList() appeared in Java 16; on older versions use collect(Collectors.toList()). The full list of constructs and methods is in the official Pattern Javadoc.

matches(), find() and lookingAt(): what is the difference

matches() returns true only if the pattern describes the entire string; lookingAt() returns true if the pattern matches the beginning of the string; find() returns true if there is a match anywhere inside it. Mixing them up is the most common reason a "correct" regex returns false.

import java.util.regex.Pattern;

public class MatchesFindExample {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("\\d+");
        for (String s : new String[]{"123", "123abc", "abc123"}) {
            System.out.println(s
                    + ": matches=" + pattern.matcher(s).matches()
                    + ", lookingAt=" + pattern.matcher(s).lookingAt()
                    + ", find=" + pattern.matcher(s).find());
        }
    }
}
// Output:
// 123: matches=true, lookingAt=true, find=true
// 123abc: matches=false, lookingAt=true, find=true
// abc123: matches=false, lookingAt=false, find=true
String matches() lookingAt() find()
"123" true true true
"123abc" false true true
"abc123" false false true

The example creates a fresh Matcher for each method on purpose: find() resumes from the position where the previous match ended, so repeated calls on the same object without reset() can give a different result.

One more example, the pattern a*b (any number of a letters followed by b):

import java.util.regex.Pattern;

public class StarExample {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("a*b");
        System.out.println(pattern.matcher("aaab").matches());
        System.out.println(pattern.matcher("b").matches());
        System.out.println(pattern.matcher("aaabc").matches());
        System.out.println(pattern.matcher("aaabc").find());
    }
}
// Output:
// true
// true
// false
// true

The string "b" matches because * allows zero repetitions. The string "aaabc" fails matches() because of the extra c at the end, yet find() locates the fragment aaab inside it.

Java regex syntax: metacharacters

Metacharacters are characters with a special meaning in a pattern: . ^ $ | ( ) [ ] { } \ ? * +. Every other character matches itself. To match a metacharacter literally, put a backslash in front of it (\., \$, \() or place it inside a set, such as [.].

Metacharacter Meaning Example Matches
. Any character except a line terminator (any character at all with the DOTALL flag) j.va java, j3va
^ Start of input (with MULTILINE, start of every line) ^Java Java at the start of the text
$ End of input (with MULTILINE, end of every line) \.txt$ .txt at the end of the text
| OR: alternative between subexpressions cat|dog cat or dog
( ) Group: bundles part of the pattern and captures the match (ab)+ ab, abab
[ ] Character set: any one of the listed characters [0-9] A single digit
{ } Exact number of repetitions \d{4} 2026
? * + Quantifiers: 0 or 1, 0 or more, 1 or more colou?r color, colour
\ Escapes a metacharacter or starts a class (\d, \s) \$\d+ $100

Character classes: \d, \s, \w and [ ] sets

A character class matches exactly one character from a given set. You define a set in square brackets ([abc]; a range is [a-c]; a negation is [^abc]), and common sets have ready-made shortcuts: \d is a digit, \s is a whitespace character, \w is a word character.

Construct What it matches In a Java string Example: yes / no
[abc] Set: one of the characters a, b or c "[abc]" b / d
[a-c] Range: any character from a to c inclusive "[a-c]" a / z
[^abc] Any character except the listed ones "[^abc]" x / a
[a-zA-Z0-9] A Latin letter of either case or a digit "[a-zA-Z0-9]" Q, 7 / _
\d A digit, same as [0-9] "\\d" 5 / x
\D Any character except a digit "\\D" x / 5
\s Whitespace: space, tab \t, newline \n, \r, \f, \x0B "\\s" space / a
\S Any non-whitespace character "\\S" a / space
\w Word character: Latin letter, digit or underscore, same as [a-zA-Z_0-9] "\\w" a, _ / é, -
\W Any character except a word character "\\W" -, é / a
\b Word boundary (a position, not a character) "\\bjava\\b" java in "I like java" / in "javascript"
\p{L} Any Unicode letter, including accented ones "\\p{L}" é, a / 5

The combination \s+ (one or more whitespace characters in a row) is the go-to pattern for splitting text into words and collapsing extra spaces; in Java code it is written as "\\s+". Examples are in split() and String methods that take a regex.

Accented letters and \w

By default, \w and \b in Java know only ASCII: \w+ splits the word "naïve" into "na" and "ve", and the range [a-z] does not include é or ü. For text in any language, use \p{L} or the UNICODE_CHARACTER_CLASS flag (example in Pattern flags).

Quantifiers: ?, *, +, {n,m}

A quantifier specifies how many times the preceding element must repeat: a character, a character class or a group. Quantifiers are greedy by default and grab as much text as possible; with an extra ? they become lazy (reluctant) and grab as little as possible.

Quantifier How many times Example Matches
a? 0 or 1 time (optional element) colou?r color, colour
a* 0 or more times ab*c ac, abc, abbbc
a+ 1 or more times ab+c abc, abbbc, but not ac
a{n} Exactly n times \d{4} 2026
a{n,} n or more times \w{3,} java, regex, but not go
a{n,m} From n to m times inclusive \d{2,4} 12, 123, 2026
*?, +?, ??, {n,m}? Lazy versions: as few repetitions as possible '.*?' Each quoted string separately
*+, ++, ?+ Possessive: greedy, but never backtrack \d++ All consecutive digits, no backtracking

What does this code print? The two patterns differ by a single question mark:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GreedyLazyExample {
    public static void main(String[] args) {
        String text = "'a' and 'b'";

        Matcher greedy = Pattern.compile("'.*'").matcher(text);
        while (greedy.find()) {
            System.out.println("greedy: " + greedy.group());
        }

        Matcher lazy = Pattern.compile("'.*?'").matcher(text);
        while (lazy.find()) {
            System.out.println("lazy: " + lazy.group());
        }
    }
}
// Output:
// greedy: 'a' and 'b'
// lazy: 'a'
// lazy: 'b'

The greedy .* first swallows everything up to the end of the string and then backs off to the last quote, which produces one long match. The lazy .*? stops at the first quote that works. A negated set gives the same result as the lazy version: '[^']*' — and it is faster, because it never backtracks.

Alternation (OR) and groups

The | operator means OR in Java regex: the pattern Java|Kotlin|Scala matches any of the three words. Parentheses ( ) turn part of a pattern into a group: they limit the scope of | and of quantifiers, and the text matched by a group is available through group(n) or as $n in a replacement string.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AlternationExample {
    public static void main(String[] args) {
        Matcher matcher = Pattern.compile("Java|Kotlin|Scala")
                .matcher("Kotlin and Scala run on the JVM, just like Java");
        while (matcher.find()) {
            System.out.println(matcher.group());
        }

        System.out.println(Pattern.compile("^cat|dog$").matcher("hotdog").find());
        System.out.println(Pattern.compile("^(cat|dog)$").matcher("hotdog").find());
    }
}
// Output:
// Kotlin
// Scala
// Java
// true
// false

| has the lowest precedence of all: ^cat|dog$ reads as "cat at the start" or "dog at the end", which is why it finds a match in "hotdog". To make the alternative apply to both anchors, wrap it in parentheses: ^(cat|dog)$. If you do not need to capture the match, use a non-capturing group (?:cat|dog).

Groups are numbered by their opening parentheses from left to right, starting at 1; group 0 is the whole match. Since Java 7, groups can have names: (?<year>\d{4}).

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GroupsExample {
    public static void main(String[] args) {
        Pattern date = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
        Matcher matcher = date.matcher("Release: 2026-10-16");
        if (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
            System.out.println(matcher.group("day"));
            System.out.println(matcher.groupCount());
        }

        String us = "2026-10-16".replaceAll("(\\d{4})-(\\d{2})-(\\d{2})", "$2/$3/$1");
        System.out.println(us);
    }
}
// Output:
// 2026-10-16
// 2026
// 16
// 3
// 10/16/2026

Pattern flags: case, multiline mode, Unicode

Flags change the behavior of the whole pattern: case-insensitive matching, multiline mode for ^ and $, Unicode support. Pass them as the second argument of Pattern.compile(regex, flags), combined with |, or switch them on inside the pattern with an embedded flag such as (?i).

Flag In the pattern What it does
CASE_INSENSITIVE (?i) Case-insensitive matching — by default for US-ASCII letters only
UNICODE_CASE (?u) Together with CASE_INSENSITIVE, folds case by Unicode rules (accented letters, other alphabets)
MULTILINE (?m) ^ and $ match at the start and end of every line
DOTALL (?s) The dot also matches line terminators
UNICODE_CHARACTER_CLASS (?U) \w, \d, \b and other classes follow Unicode (Java 7+); implies UNICODE_CASE
COMMENTS (?x) Whitespace in the pattern is ignored, # starts a comment
LITERAL — The whole pattern is treated as plain text
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FlagsExample {
    public static void main(String[] args) {
        System.out.println(Pattern.compile("café", Pattern.CASE_INSENSITIVE)
                .matcher("CAFÉ").matches());
        System.out.println(Pattern.compile("café", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)
                .matcher("CAFÉ").matches());
        System.out.println("JAVA".matches("(?i)java"));

        Matcher ascii = Pattern.compile("\\w+").matcher("Café, Java");
        while (ascii.find()) {
            System.out.println("default: " + ascii.group());
        }
        Matcher unicode = Pattern.compile("\\w+", Pattern.UNICODE_CHARACTER_CLASS).matcher("Café, Java");
        while (unicode.find()) {
            System.out.println("UNICODE_CHARACTER_CLASS: " + unicode.group());
        }
    }
}
// Output:
// false
// true
// true
// default: Caf
// default: Java
// UNICODE_CHARACTER_CLASS: Café
// UNICODE_CHARACTER_CLASS: Java

Two lines of this output are easy to get wrong. The first one: CASE_INSENSITIVE on its own folds case only for ASCII letters, so é and É are different characters until you add UNICODE_CASE. And without UNICODE_CHARACTER_CLASS, \w+ silently cuts "Café" down to "Caf" — no exception, just a wrong result.

split(): splitting a string by regex

The split() method breaks a string into an array of substrings, treating every match of the regular expression as a delimiter. It exists in the String class (str.split(regex)) and in the Pattern class (pattern.split(str)); the result is the same, but Pattern is more efficient when the same delimiter is used many times.

import java.util.Arrays;
import java.util.regex.Pattern;

public class PatternSplitExample {
    public static void main(String[] args) {
        String text = "java5tiger 77 java6mustang";

        Pattern pattern = Pattern.compile("\\d+\\s?");
        System.out.println(Arrays.toString(pattern.split(text)));

        System.out.println(Arrays.toString(text.split("\\s*\\d+\\s*")));
    }
}
// Output:
// [java, tiger , java, mustang]
// [java, tiger, java, mustang]

Notice "tiger " with a trailing space in the first line: \d+\s? captures a space only after the digits, so the space before 77 stays in the previous element. The pattern \s*\d+\s* consumes spaces on both sides.

Splitting on whitespace with \s+, plus a few cases that surprise people:

import java.util.Arrays;
import java.util.regex.Pattern;

public class SplitEdgeCases {
    public static void main(String[] args) {
        String words = "  Java   regex\tis  simple ";
        System.out.println(Arrays.toString(words.split("\\s+")));
        System.out.println(Arrays.toString(words.strip().split("\\s+")));

        String ip = "192.168.0.1";
        System.out.println(ip.split(".").length);
        System.out.println(Arrays.toString(ip.split("\\.")));

        System.out.println(Arrays.toString("a|b|c".split("|")));
        System.out.println(Arrays.toString("a|b|c".split(Pattern.quote("|"))));

        System.out.println(Arrays.toString("a,b,,".split(",")));
        System.out.println(Arrays.toString("a,b,,".split(",", -1)));
    }
}
// Output:
// [, Java, regex, is, simple]
// [Java, regex, is, simple]
// 0
// [192, 168, 0, 1]
// [a, |, b, |, c]
// [a, b, c]
// [a, b]
// [a, b, , ]
Call Result Why
" a b".split("\\s+") The first element is an empty string There is an "empty word" before the leading spaces; remove them with strip() (Java 11) or trim()
"1.2.3".split(".") Empty array The dot matches any character; all pieces are empty, and trailing empty strings are dropped
"a|b".split("|") Split after every character | with empty alternatives matches the empty string; use "\\|" or Pattern.quote("|")
"a,b,,".split(",") [a, b] Trailing empty strings are removed; split(",", -1) keeps them

String methods that take a regex

Four methods of the String class accept a regular expression: matches(), split(), replaceAll() and replaceFirst(). The replace() method does not use regex and replaces text literally — confusing replace() with replaceAll() is one of the most frequent Java string bugs.

String method What it does Equivalent with Pattern
matches(regex) The whole string matches the pattern Pattern.matches(regex, str)
split(regex), split(regex, limit) Splits the string around matches Pattern.compile(regex).split(str)
replaceAll(regex, replacement) Replaces all matches Pattern.compile(regex).matcher(str).replaceAll(r)
replaceFirst(regex, replacement) Replaces the first match ...matcher(str).replaceFirst(r)
replace(target, replacement) Replaces all occurrences literally, no regex —
public class StringRegexExample {
    public static void main(String[] args) {
        System.out.println("a.b.c".replace(".", "-"));
        System.out.println("a.b.c".replaceAll(".", "-"));
        System.out.println("a.b.c".replaceAll("\\.", "-"));
        System.out.println("[" + "  Java   regex  ".replaceAll("\\s+", " ") + "]");
        System.out.println("12345".matches("\\d+"));
        System.out.println("Price: 100".replaceAll("100", "200$"));
    }
}
// Output:
// a-b-c
// -----
// a-b-c
// [ Java regex ]
// true
// Exception in thread "main" java.lang.IllegalArgumentException: Illegal group reference: group index is missing

In the replacement string of replaceAll(), $ starts a group reference and \ escapes, so "200$" throws an exception. A dollar sign in front fails differently: "$200" is read as a reference to group 2 and throws IndexOutOfBoundsException: No group 2. If the replacement is arbitrary text, pass it through Matcher.quoteReplacement("$200") — then the result is Price: $200. Note that $ here has nothing to do with the % placeholders of String.format().

String.matches() and replaceAll() compile the pattern on every call. When you loop over thousands of strings, move the Pattern into a private static final field and call pattern.matcher(s).

Examples: domain check and finding emails

In practice, regular expressions are most often used for two jobs: checking that an entire string has the right format (matches()) and finding every fragment of a certain shape in a text (find() in a loop). Below is one Java regex example for each.

Validating a domain name

import java.util.regex.Pattern;

public class DomainExample {
    private static final Pattern DOMAIN = Pattern.compile(".+\\.(com|org|net)");

    public static void main(String[] args) {
        System.out.println(test("google.com"));
        System.out.println(test("wikipedia.org"));
        System.out.println(test("example.io"));
    }

    public static boolean test(String testString) {
        return DOMAIN.matcher(testString).matches();
    }
}
// Output:
// true
// true
// false

The pattern requires the string to end with a dot and one of three zones listed with |. This is a teaching example: .+ also lets spaces through, as in "a b.com". For real URLs, parsing the string with java.net.URI is more reliable.

Finding emails in a text

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class EmailExample {
    private static final Pattern EMAIL = Pattern.compile("([\\w.+-]+)@([\\w.-]+\\.[a-z]{2,})");

    public static void main(String[] args) {
        String text = "Contact us: [email protected], [email protected]!";
        Matcher matcher = EMAIL.matcher(text);
        while (matcher.find()) {
            System.out.println("email: " + matcher.group()
                    + ", user: " + matcher.group(1)
                    + ", domain: " + matcher.group(2));
        }
    }
}
// Output:
// email: [email protected], user: john.smith, domain: gmail.com
// email: [email protected], user: support, domain: example.co.uk

Group 1 captures the user name (letters, digits, _ . + -), group 2 the domain with a top-level zone of two or more Latin letters; multi-level domains such as example.co.uk work because [\w.-]+ backtracks until \.[a-z]{2,} can match the last zone. Full email validation per RFC 5322 in a single regex is practically unreadable, so real projects use a regex as a first filter and confirm the address by sending an email.

Regex gotchas and how to fix them

Most regex mistakes in Java slip past the compiler: a pattern is just a string, so the problem shows up only at runtime — as an exception, a wrong result or a sudden slowdown. The most common cases and their fixes:

Code What happens How to fix it
Pattern.compile("\d+") Compilation error: illegal escape character Double the backslash: "\\d+"
Pattern.compile("[a-z") PatternSyntaxException: Unclosed character class near index 3 Close the bracket: "[a-z]"
"abc123".matches("\\d+") false, although the string contains digits To search inside a string, use matcher.find()
matcher.group() without calling find() IllegalStateException: No match found Call if (matcher.find()) or matches() first
"1.2.3".split(".") Empty array split("\\.") or Pattern.quote(".")
replaceAll("100", "200$") IllegalArgumentException: Illegal group reference Matcher.quoteReplacement("200$")
Nested quantifiers such as "(a+)+b" Risk of catastrophic backtracking (ReDoS): on a long string without a match, the number of attempts grows exponentially Do not nest quantifiers ("a+b"), use possessive ++
s.matches(regex) in a loop The pattern is recompiled on every iteration private static final Pattern + matcher(s)

Frequently Asked Questions

Are Pattern and Matcher thread-safe?

Pattern is immutable and thread-safe: a single instance in a static final field can be shared by any number of threads. Matcher keeps search state and is not thread-safe — each thread should create its own with pattern.matcher(text).

How do I check that a string contains only digits?

str.matches("[0-9]+") returns true only for a non-empty string of digits; an empty string gives false, whereas [0-9]* would accept it. If you then convert the string to a number, remember that Integer.parseInt() throws NumberFormatException for numbers that are too long, even though the regex let them through.

How can one regex check password strength?

With lookaheads (?=...): they test a condition without moving the current position. password.matches("(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}") requires at least 8 characters, at least one digit, one lowercase and one uppercase Latin letter. There are also lookbehinds: (?<=...) and (?<!...).

Can I avoid doubling backslashes in Java regex?

No. Raw string literals (JEP 326) were planned for Java 12 but withdrawn. Text blocks from Java 15 still process escape sequences, so backslashes are doubled there too. You can reduce their number with character sets ([.] instead of \\.) and Pattern.quote().

Comments

Please log in or register to have a possibility to add comment.