String Processing
Regular Expressions Introduction
When validating user input or searching for patterns in text, regular expressions provide a compact language for matching. Regex fundamentals help you write validation, search, extraction, and replacement logic.
Literal Matching
Literal.java
Replay: real traced execution (multi-file project)
// Literal matching
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Literal {
public static void main(String[] args) {
// Literal match
String text1 = "hello";
boolean matches1 = text1.matches("hello");
System.out.println("'hello' matches 'hello': " + matches1);
boolean matches2 = text1.matches("world");
System.out.println("'hello' matches 'world': " + matches2);
// Pattern and Matcher
Pattern pattern = Pattern.compile("hello");
Matcher matcher1 = pattern.matcher("hello");
System.out.println("\nMatcher matches: " + matcher1.matches());
Matcher matcher2 = pattern.matcher("hello world");
System.out.println("Matcher matches 'hello world': " + matcher2.matches());
// Find pattern (doesn't require full match)
Matcher matcher3 = pattern.matcher("hello world");
System.out.println("Find 'hello' in 'hello world': " + matcher3.find());
// Case sensitivity
boolean matches3 = "Hello".matches("hello");
System.out.println("\n'Hello' matches 'hello': " + matches3);
// Case insensitive
Pattern caseInsensitive = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
Matcher matcher4 = caseInsensitive.matcher("Hello");
System.out.println("Case insensitive match: " + matcher4.matches());
// Multiple occurrences
String text2 = "hello hello hello";
Matcher matcher5 = pattern.matcher(text2);
System.out.println("\nFind all occurrences:");
while (matcher5.find()) {
System.out.println(" Found at index: " + matcher5.start());
}
}
}
// Literal matching
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Literal {
public static void main(String[] args) {
// Literal match
String text1 = "world";
boolean matches1 = text1.matches("hello");
System.out.println("'hello' matches 'hello': " + matches1);
boolean matches2 = text1.matches("world");
System.out.println("'hello' matches 'world': " + matches2);
// Pattern and Matcher
Pattern pattern = Pattern.compile("hello");
Matcher matcher1 = pattern.matcher("hello");
System.out.println("\nMatcher matches: " + matcher1.matches());
Matcher matcher2 = pattern.matcher("hello world");
System.out.println("Matcher matches 'hello world': " + matcher2.matches());
// Find pattern (doesn't require full match)
Matcher matcher3 = pattern.matcher("hello world");
System.out.println("Find 'hello' in 'hello world': " + matcher3.find());
// Case sensitivity
boolean matches3 = "Hello".matches("hello");
System.out.println("\n'Hello' matches 'hello': " + matches3);
// Case insensitive
Pattern caseInsensitive = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
Matcher matcher4 = caseInsensitive.matcher("Hello");
System.out.println("Case insensitive match: " + matcher4.matches());
// Multiple occurrences
String text2 = "hello hello hello";
Matcher matcher5 = pattern.matcher(text2);
System.out.println("\nFind all occurrences:");
while (matcher5.find()) {
System.out.println(" Found at index: " + matcher5.start());
}
}
}
text1 ← hello, matches1 ← true, matches2 ← false, pattern ← hello
8public static void main(String[] args) {9 // Literal match10 String text1→ hello = "hello"; //@text1="hello", "world"11 boolean matches1→ true = text1.matches("hello");12 System.out.println("'hello' matches 'hello': " + matches1true);1314 boolean matches2→ false = text1.matches("world");15 System.out.println("'hello' matches 'world': " + matches2false);1617 // Pattern and Matcher18 Pattern pattern→ hello = Pattern.compile("hello");19 Matcher matcher1→ java.util.regex.Matcher[pattern=hello region=0,5 lastmatch=] = pattern.matcher("hello");20 System.out.println("\nMatcher matches: " + matcher1.matches());2122 Matcher matcher2→ java.util.regex.Matcher[pattern=hello region=0,11 lastmatch=] = pattern.matcher("hello world");23 System.out.println("Matcher matches 'hello world': " + matcher2.matches());2425 // Find pattern (doesn't require full match)26 Matcher matcher3→ java.util.regex.Matcher[pattern=hello region=0,11 lastmatch=] = pattern.matcher("hello world");27 System.out.println("Find 'hello' in 'hello world': " + matcher3.find());2829 // Case sensitivity30 boolean matches3→ false = "Hello".matches("hello");31 System.out.println("\n'Hello' matches 'hello': " + matches3false);3233 // Case insensitive34 Pattern caseInsensitive→ hello = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);35 Matcher matcher4→ java.util.regex.Matcher[pattern=hello region=0,5 lastmatch=] = caseInsensitive.matcher("Hello");36 System.out.println("Case insensitive match: " + matcher4.matches());3738 // Multiple occurrences39 String text2→ hello hello hello = "hello hello hello";40 Matcher matcher5→ java.util.regex.Matcher[pattern=hello region=0,17 lastmatch=] = pattern.matcher(text2hello hello hello);4142 System.out.println("\nFind all occurrences:");43 while (matcher5.find()) {output'hello' matches 'hello': true 'hello' matches 'world': false Matcher matches: true Matcher matches 'hello world': false Find 'hello' in 'hello world': true 'Hello' matches 'hello': false Case insensitive match: true Find all occurrences:while (matcher5.find())
pass 1 of 342System.out.println("\nFind all occurrences:");43while (matcher5.find()) {44 System.out.println(" Found at index: " + matcher5.start());45}output Found at index: 0
text1 ← world, matches1 ← false, matches2 ← true, pattern ← hello
8public static void main(String[] args) {9 // Literal match10 String text1→ world = "world";11 boolean matches1→ false = text1.matches("hello");12 System.out.println("'hello' matches 'hello': " + matches1false);1314 boolean matches2→ true = text1.matches("world");15 System.out.println("'hello' matches 'world': " + matches2true);1617 // Pattern and Matcher18 Pattern pattern→ hello = Pattern.compile("hello");19 Matcher matcher1→ java.util.regex.Matcher[pattern=hello region=0,5 lastmatch=] = pattern.matcher("hello");20 System.out.println("\nMatcher matches: " + matcher1.matches());2122 Matcher matcher2→ java.util.regex.Matcher[pattern=hello region=0,11 lastmatch=] = pattern.matcher("hello world");23 System.out.println("Matcher matches 'hello world': " + matcher2.matches());2425 // Find pattern (doesn't require full match)26 Matcher matcher3→ java.util.regex.Matcher[pattern=hello region=0,11 lastmatch=] = pattern.matcher("hello world");27 System.out.println("Find 'hello' in 'hello world': " + matcher3.find());2829 // Case sensitivity30 boolean matches3→ false = "Hello".matches("hello");31 System.out.println("\n'Hello' matches 'hello': " + matches3false);3233 // Case insensitive34 Pattern caseInsensitive→ hello = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);35 Matcher matcher4→ java.util.regex.Matcher[pattern=hello region=0,5 lastmatch=] = caseInsensitive.matcher("Hello");36 System.out.println("Case insensitive match: " + matcher4.matches());3738 // Multiple occurrences39 String text2→ hello hello hello = "hello hello hello";40 Matcher matcher5→ java.util.regex.Matcher[pattern=hello region=0,17 lastmatch=] = pattern.matcher(text2hello hello hello);4142 System.out.println("\nFind all occurrences:");43 while (matcher5.find()) {output'hello' matches 'hello': false 'hello' matches 'world': true Matcher matches: true Matcher matches 'hello world': false Find 'hello' in 'hello world': true 'Hello' matches 'hello': false Case insensitive match: true Find all occurrences:while (matcher5.find())
pass 1 of 342System.out.println("\nFind all occurrences:");43while (matcher5.find()) {44 System.out.println(" Found at index: " + matcher5.start());45}output Found at index: 0
pattern
A string that defines search criteria. It can include literal characters and special metacharacters.
Character Classes
CharacterClass.java
Replay: real traced execution (multi-file project)
// Character classes
import java.util.regex.Pattern;
public class CharacterClass {
public static void main(String[] args) {
// Match one of specific characters
System.out.println("a".matches("[abc]")); // true
System.out.println("b".matches("[abc]")); // true
System.out.println("d".matches("[abc]")); // false
// Range
System.out.println("\nRanges:");
System.out.println("5".matches("[0-9]")); // true - digit
System.out.println("m".matches("[a-z]")); // true - lowercase
System.out.println("M".matches("[A-Z]")); // true - uppercase
System.out.println("M".matches("[a-z]")); // false
// Multiple ranges
System.out.println("\nMultiple ranges:");
System.out.println("a".matches("[a-zA-Z]")); // true - any letter
System.out.println("5".matches("[a-zA-Z]")); // false
System.out.println("5".matches("[a-zA-Z0-9]")); // true - alphanumeric
// Negation [^...]
System.out.println("\nNegation:");
System.out.println("a".matches("[^0-9]")); // true - not a digit
System.out.println("5".matches("[^0-9]")); // false - is a digit
// Predefined character classes
System.out.println("\nPredefined classes:");
System.out.println("5".matches("\\d")); // digit
System.out.println("a".matches("\\d")); // false
System.out.println("a".matches("\\w")); // word char
System.out.println(" ".matches("\\s")); // whitespace
System.out.println("a".matches("\\D")); // non-digit
System.out.println("5".matches("\\D")); // false
// Dot . matches any character
System.out.println("\nDot (any char):");
System.out.println("a".matches(".")); // true
System.out.println("5".matches(".")); // true
System.out.println(" ".matches(".")); // true
}
}
public static void main(String[] args)
7public static void main(String[] args) {8 // Match one of specific characters9 System.out.println("a".matches("[abc]")); // true10 System.out.println("b".matches("[abc]")); // true11 System.out.println("d".matches("[abc]")); // false1213 // Range14 System.out.println("\nRanges:");15 System.out.println("5".matches("[0-9]")); // true - digit16 System.out.println("m".matches("[a-z]")); // true - lowercase17 System.out.println("M".matches("[A-Z]")); // true - uppercase18 System.out.println("M".matches("[a-z]")); // false1920 // Multiple ranges21 System.out.println("\nMultiple ranges:");22 System.out.println("a".matches("[a-zA-Z]")); // true - any letter23 System.out.println("5".matches("[a-zA-Z]")); // false24 System.out.println("5".matches("[a-zA-Z0-9]")); // true - alphanumeric2526 // Negation [^...]27 System.out.println("\nNegation:");28 System.out.println("a".matches("[^0-9]")); // true - not a digit29 System.out.println("5".matches("[^0-9]")); // false - is a digit3031 // Predefined character classes32 System.out.println("\nPredefined classes:");33 System.out.println("5".matches("\\d")); // digit34 System.out.println("a".matches("\\d")); // false35 System.out.println("a".matches("\\w")); // word char36 System.out.println(" ".matches("\\s")); // whitespace37 System.out.println("a".matches("\\D")); // non-digit38 System.out.println("5".matches("\\D")); // false3940 // Dot . matches any character41 System.out.println("\nDot (any char):");42 System.out.println("a".matches(".")); // true43 System.out.println("5".matches(".")); // true44 System.out.println(" ".matches(".")); // true45}outputtrue true false Ranges: true true true false Multiple ranges: true false true Negation: true false Predefined classes: true false true true true false Dot (any char): true true true
character_class
Square brackets such as [abc] match any single character from a set. Ranges such as [a-z] match a span of characters.
Quantifiers
Quantifiers.java
Replay: real traced execution (multi-file project)
// Quantifiers
public class Quantifiers {
public static void main(String[] args) {
// * (0 or more)
System.out.println("Asterisk * (0 or more):");
System.out.println("".matches("a*")); // true - 0 a's
System.out.println("a".matches("a*")); // true - 1 a
System.out.println("aaa".matches("a*")); // true - 3 a's
System.out.println("b".matches("a*")); // false - not a
// + (1 or more)
System.out.println("\nPlus + (1 or more):");
System.out.println("".matches("a+")); // false - 0 a's
System.out.println("a".matches("a+")); // true - 1 a
System.out.println("aaa".matches("a+")); // true - 3 a's
// ? (0 or 1)
System.out.println("\nQuestion ? (0 or 1):");
System.out.println("".matches("a?")); // true - 0 a's
System.out.println("a".matches("a?")); // true - 1 a
System.out.println("aa".matches("a?")); // false - 2 a's
// {n} (exactly n)
System.out.println("\n{n} (exactly n):");
System.out.println("aa".matches("a{2}")); // true
System.out.println("aaa".matches("a{2}")); // false
System.out.println("a".matches("a{2}")); // false
// {n,} (n or more)
System.out.println("\n{n,} (n or more):");
System.out.println("aa".matches("a{2,}")); // true - 2 a's
System.out.println("aaa".matches("a{2,}")); // true - 3 a's
System.out.println("a".matches("a{2,}")); // false - only 1
// {n,m} (between n and m)
System.out.println("\n{n,m} (between n and m):");
System.out.println("aa".matches("a{2,4}")); // true
System.out.println("aaa".matches("a{2,4}")); // true
System.out.println("aaaa".matches("a{2,4}")); // true
System.out.println("a".matches("a{2,4}")); // false - too few
System.out.println("aaaaa".matches("a{2,4}")); // false - too many
// Practical: digits
System.out.println("\nPractical - validate numbers:");
System.out.println("123".matches("\\d+")); // true - one or more digits
System.out.println("12345".matches("\\d{5}")); // true - exactly 5 digits
System.out.println("123".matches("\\d{2,4}")); // true - 2-4 digits
}
}
public static void main(String[] args)
5public static void main(String[] args) {6 // * (0 or more)7 System.out.println("Asterisk * (0 or more):");8 System.out.println("".matches("a*")); // true - 0 a's9 System.out.println("a".matches("a*")); // true - 1 a10 System.out.println("aaa".matches("a*")); // true - 3 a's11 System.out.println("b".matches("a*")); // false - not a1213 // + (1 or more)14 System.out.println("\nPlus + (1 or more):");15 System.out.println("".matches("a+")); // false - 0 a's16 System.out.println("a".matches("a+")); // true - 1 a17 System.out.println("aaa".matches("a+")); // true - 3 a's1819 // ? (0 or 1)20 System.out.println("\nQuestion ? (0 or 1):");21 System.out.println("".matches("a?")); // true - 0 a's22 System.out.println("a".matches("a?")); // true - 1 a23 System.out.println("aa".matches("a?")); // false - 2 a's2425 // {n} (exactly n)26 System.out.println("\n{n} (exactly n):");27 System.out.println("aa".matches("a{2}")); // true28 System.out.println("aaa".matches("a{2}")); // false29 System.out.println("a".matches("a{2}")); // false3031 // {n,} (n or more)32 System.out.println("\n{n,} (n or more):");33 System.out.println("aa".matches("a{2,}")); // true - 2 a's34 System.out.println("aaa".matches("a{2,}")); // true - 3 a's35 System.out.println("a".matches("a{2,}")); // false - only 13637 // {n,m} (between n and m)38 System.out.println("\n{n,m} (between n and m):");39 System.out.println("aa".matches("a{2,4}")); // true40 System.out.println("aaa".matches("a{2,4}")); // true41 System.out.println("aaaa".matches("a{2,4}")); // true42 System.out.println("a".matches("a{2,4}")); // false - too few43 System.out.println("aaaaa".matches("a{2,4}")); // false - too many4445 // Practical: digits46 System.out.println("\nPractical - validate numbers:");47 System.out.println("123".matches("\\d+")); // true - one or more digits48 System.out.println("12345".matches("\\d{5}")); // true - exactly 5 digits49 System.out.println("123".matches("\\d{2,4}")); // true - 2-4 digits50}outputAsterisk * (0 or more): true true true false Plus + (1 or more): false true true Question ? (0 or 1): true true false {n} (exactly n): true false false {n,} (n or more): true true false {n,m} (between n and m): true true true false false Practical - validate numbers: true true true
quantifier
A symbol that specifies how many times the preceding element should match, such as *, +, ?, or {n}.
Anchors
Anchors.java
Replay: real traced execution (multi-file project)
// Anchors
public class Anchors {
public static void main(String[] args) {
// ^ (start of string)
System.out.println("Start anchor ^:");
System.out.println("hello".matches("^hello")); // true
System.out.println("hello world".matches("^hello")); // false - matches() requires full match
System.out.println("world hello".matches("^hello")); // false
// For partial matching, use find()
System.out.println("\nUsing find() with ^:");
System.out.println("hello world".matches("hello.*")); // true - starts with hello
System.out.println("world hello".matches("hello.*")); // false
// $ (end of string)
System.out.println("\nEnd anchor $:");
System.out.println("hello".matches(".*hello$")); // true
System.out.println("hello world".matches(".*world$")); // true
System.out.println("world hello".matches(".*world$")); // false
// Both anchors
System.out.println("\nBoth anchors ^...$:");
System.out.println("hello".matches("^hello$")); // true - exact match
System.out.println("hello world".matches("^hello$")); // false
// \b (word boundary)
System.out.println("\nWord boundary \\b:");
String text = "hello world";
System.out.println(text.matches(".*\\bhello\\b.*")); // true - hello as word
System.out.println(text.matches(".*\\bworld\\b.*")); // true - world as word
System.out.println("helloworld".matches(".*\\bhello\\b.*")); // false - no boundary
// Practical examples
System.out.println("\nPractical validation:");
// Must start with letter
System.out.println("abc123".matches("^[a-zA-Z].*")); // true
System.out.println("123abc".matches("^[a-zA-Z].*")); // false
// Must end with digit
System.out.println("abc123".matches(".*\\d$")); // true
System.out.println("abc".matches(".*\\d$")); // false
// Exact length
System.out.println("12345".matches("^\\d{5}$")); // true - exactly 5 digits
System.out.println("1234".matches("^\\d{5}$")); // false
}
}
text ← hello world
5public static void main(String[] args) {6 // ^ (start of string)7 System.out.println("Start anchor ^:");8 System.out.println("hello".matches("^hello")); // true9 System.out.println("hello world".matches("^hello")); // false - matches() requires full match10 System.out.println("world hello".matches("^hello")); // false1112 // For partial matching, use find()13 System.out.println("\nUsing find() with ^:");14 System.out.println("hello world".matches("hello.*")); // true - starts with hello15 System.out.println("world hello".matches("hello.*")); // false1617 // $ (end of string)18 System.out.println("\nEnd anchor $:");19 System.out.println("hello".matches(".*hello$")); // true20 System.out.println("hello world".matches(".*world$")); // true21 System.out.println("world hello".matches(".*world$")); // false2223 // Both anchors24 System.out.println("\nBoth anchors ^...$:");25 System.out.println("hello".matches("^hello$")); // true - exact match26 System.out.println("hello world".matches("^hello$")); // false2728 // \b (word boundary)29 System.out.println("\nWord boundary \\b:");30 String text→ hello world = "hello world";31 System.out.println(text.matches(".*\\bhello\\b.*")); // true - hello as word32 System.out.println(text.matches(".*\\bworld\\b.*")); // true - world as word33 System.out.println("helloworld".matches(".*\\bhello\\b.*")); // false - no boundary3435 // Practical examples36 System.out.println("\nPractical validation:");3738 // Must start with letter39 System.out.println("abc123".matches("^[a-zA-Z].*")); // true40 System.out.println("123abc".matches("^[a-zA-Z].*")); // false4142 // Must end with digit43 System.out.println("abc123".matches(".*\\d$")); // true44 System.out.println("abc".matches(".*\\d$")); // false4546 // Exact length47 System.out.println("12345".matches("^\\d{5}$")); // true - exactly 5 digits48 System.out.println("1234".matches("^\\d{5}$")); // false49}outputStart anchor ^: true false false Using find() with ^: true false End anchor $: true true false Both anchors ^...$: true false Word boundary \b: true true false Practical validation: true false true false true false
anchor
An anchor matches a position rather than a character, such as start of string, end of string, or a word boundary.
Groups
Groups.java
Replay: real traced execution (multi-file project)
// Groups and capturing
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Groups {
public static void main(String[] args) {
// Basic grouping
String date = "2025-01-29";
Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = pattern.matcher(date);
if (matcher.matches()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Year: " + matcher.group(1));
System.out.println("Month: " + matcher.group(2));
System.out.println("Day: " + matcher.group(3));
}
// Email parsing
String email = "user@example.com";
Pattern emailPattern = Pattern.compile("([^@]+)@([^@]+)");
Matcher emailMatcher = emailPattern.matcher(email);
if (emailMatcher.matches()) {
System.out.println("\nEmail parts:");
System.out.println("Username: " + emailMatcher.group(1));
System.out.println("Domain: " + emailMatcher.group(2));
}
// Phone number
String phone = "(555) 123-4567";
Pattern phonePattern = Pattern.compile("\\((\\d{3})\\)\\s(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher(phone);
if (phoneMatcher.matches()) {
System.out.println("\nPhone parts:");
System.out.println("Area: " + phoneMatcher.group(1));
System.out.println("Exchange: " + phoneMatcher.group(2));
System.out.println("Number: " + phoneMatcher.group(3));
}
// Multiple matches
String text = "Call me at 555-1234 or 555-5678";
Pattern numPattern = Pattern.compile("(\\d{3})-(\\d{4})");
Matcher numMatcher = numPattern.matcher(text);
System.out.println("\nAll phone numbers:");
while (numMatcher.find()) {
System.out.println(" " + numMatcher.group(0) +
" (Area: " + numMatcher.group(1) +
", Num: " + numMatcher.group(2) + ")");
}
// Non-capturing group (?:...)
String url = "https://example.com";
Pattern urlPattern = Pattern.compile("(https?)://(.+)");
Matcher urlMatcher = urlPattern.matcher(url);
if (urlMatcher.matches()) {
System.out.println("\nURL parts:");
System.out.println("Protocol: " + urlMatcher.group(1));
System.out.println("Domain: " + urlMatcher.group(2));
}
}
}
// Groups and capturing
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Groups {
public static void main(String[] args) {
// Basic grouping
String date = "2026-12-05";
Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = pattern.matcher(date);
if (matcher.matches()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Year: " + matcher.group(1));
System.out.println("Month: " + matcher.group(2));
System.out.println("Day: " + matcher.group(3));
}
// Email parsing
String email = "user@example.com";
Pattern emailPattern = Pattern.compile("([^@]+)@([^@]+)");
Matcher emailMatcher = emailPattern.matcher(email);
if (emailMatcher.matches()) {
System.out.println("\nEmail parts:");
System.out.println("Username: " + emailMatcher.group(1));
System.out.println("Domain: " + emailMatcher.group(2));
}
// Phone number
String phone = "(555) 123-4567";
Pattern phonePattern = Pattern.compile("\\((\\d{3})\\)\\s(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher(phone);
if (phoneMatcher.matches()) {
System.out.println("\nPhone parts:");
System.out.println("Area: " + phoneMatcher.group(1));
System.out.println("Exchange: " + phoneMatcher.group(2));
System.out.println("Number: " + phoneMatcher.group(3));
}
// Multiple matches
String text = "Call me at 555-1234 or 555-5678";
Pattern numPattern = Pattern.compile("(\\d{3})-(\\d{4})");
Matcher numMatcher = numPattern.matcher(text);
System.out.println("\nAll phone numbers:");
while (numMatcher.find()) {
System.out.println(" " + numMatcher.group(0) +
" (Area: " + numMatcher.group(1) +
", Num: " + numMatcher.group(2) + ")");
}
// Non-capturing group (?:...)
String url = "https://example.com";
Pattern urlPattern = Pattern.compile("(https?)://(.+)");
Matcher urlMatcher = urlPattern.matcher(url);
if (urlMatcher.matches()) {
System.out.println("\nURL parts:");
System.out.println("Protocol: " + urlMatcher.group(1));
System.out.println("Domain: " + urlMatcher.group(2));
}
}
}
date ← 2025-01-29, pattern ← (\d{4})-(\d{2})-(\d{2}), matcher ← java.util.regex.Matcher[pattern=(\d{4})-(\d{2})-(\d{2}) region=0,10 lastmatch=]
8public static void main(String[] args) {9 // Basic grouping10 String date→ 2025-01-29 = "2025-01-29"; //@date="2025-01-29", "2026-12-05"11 Pattern pattern→ (\d{4})-(\d{2})-(\d{2}) = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");12 Matcher matcher→ java.util.regex.Matcher[pattern=(\d{4})-(\d{2})-(\d{2}) region=0,10 lastmatch=] = pattern.matcher(date2025-01-29);if (matcher.matches())
14if (matcher.matches()) {15 System.out.println("Full match: " + matcher.group(0));16 System.out.println("Year: " + matcher.group(1));17 System.out.println("Month: " + matcher.group(2));18 System.out.println("Day: " + matcher.group(3));19}outputFull match: 2025-01-29 Year: 2025 Month: 01 Day: 29email ← user@example.com, emailPattern ← ([^@]+)@([^@]+), emailMatcher ← java.util.regex.Matcher[pattern=([^@]+)@([^@]+) region=0,16 lastmatch=]
21// Email parsing22String email→ user@example.com = "user@example.com";23Pattern emailPattern→ ([^@]+)@([^@]+) = Pattern.compile("([^@]+)@([^@]+)");24Matcher emailMatcher→ java.util.regex.Matcher[pattern=([^@]+)@([^@]+) region=0,16 lastmatch=] = emailPattern.matcher(emailuser@example.com);if (emailMatcher.matches())
26if (emailMatcher.matches()) {27 System.out.println("\nEmail parts:");28 System.out.println("Username: " + emailMatcher.group(1));29 System.out.println("Domain: " + emailMatcher.group(2));30}output Email parts: Username: user Domain: example.comphone ← (555) 123-4567, phonePattern ← \((\d{3})\)\s(\d{3})-(\d{4})
32// Phone number33String phone→ (555) 123-4567 = "(555) 123-4567";34Pattern phonePattern→ \((\d{3})\)\s(\d{3})-(\d{4}) = Pattern.compile("\\((\\d{3})\\)\\s(\\d{3})-(\\d{4})");35Matcher phoneMatcher→ java.util.regex.Matcher[pattern=\((\d{3})\)\s(\d{3})-(\d{4}) region=0,14 lastmatch=] = phonePattern.matcher(phone(555) 123-4567);if (phoneMatcher.matches())
37if (phoneMatcher.matches()) {38 System.out.println("\nPhone parts:");39 System.out.println("Area: " + phoneMatcher.group(1));40 System.out.println("Exchange: " + phoneMatcher.group(2));41 System.out.println("Number: " + phoneMatcher.group(3));42}output Phone parts: Area: 555 Exchange: 123 Number: 4567text ← Call me at 555-1234 or 555-5678, numPattern ← (\d{3})-(\d{4})
44// Multiple matches45String text→ Call me at 555-1234 or 555-5678 = "Call me at 555-1234 or 555-5678";46Pattern numPattern→ (\d{3})-(\d{4}) = Pattern.compile("(\\d{3})-(\\d{4})");47Matcher numMatcher→ java.util.regex.Matcher[pattern=(\d{3})-(\d{4}) region=0,31 lastmatch=] = numPattern.matcher(textCall me at 555-1234 or 555-5678);4849System.out.println("\nAll phone numbers:");50while (numMatcher.find()) {output All phone numbers:while (numMatcher.find())
pass 1 of 249System.out.println("\nAll phone numbers:");50while (numMatcher.find()) {51 System.out.println(" " + numMatcher.group(0) + 52 " (Area: " + numMatcher.group(1) + 53 ", Num: " + numMatcher.group(2) + ")");54}output 555-1234 (Area: 555, Num: 1234)while (numMatcher.find())
pass 2 of 249System.out.println("\nAll phone numbers:");50while (numMatcher.find()) {51 System.out.println(" " + numMatcher.group(0) + 52 " (Area: " + numMatcher.group(1) + 53 ", Num: " + numMatcher.group(2) + ")");54}output 555-5678 (Area: 555, Num: 5678)url ← https://example.com, urlPattern ← (https?)://(.+), urlMatcher ← java.util.regex.Matcher[pattern=(https?)://(.+) region=0,19 lastmatch=]
56// Non-capturing group (?:...)57String url→ https://example.com = "https://example.com";58Pattern urlPattern→ (https?)://(.+) = Pattern.compile("(https?)://(.+)");59Matcher urlMatcher→ java.util.regex.Matcher[pattern=(https?)://(.+) region=0,19 lastmatch=] = urlPattern.matcher(urlhttps://example.com);if (urlMatcher.matches())
61if (urlMatcher.matches()) {62 System.out.println("\nURL parts:");63 System.out.println("Protocol: " + urlMatcher.group(1));64 System.out.println("Domain: " + urlMatcher.group(2));65}output URL parts: Protocol: https Domain: example.com
date ← 2026-12-05, pattern ← (\d{4})-(\d{2})-(\d{2}), matcher ← java.util.regex.Matcher[pattern=(\d{4})-(\d{2})-(\d{2}) region=0,10 lastmatch=]
8public static void main(String[] args) {9 // Basic grouping10 String date→ 2026-12-05 = "2026-12-05";11 Pattern pattern→ (\d{4})-(\d{2})-(\d{2}) = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");12 Matcher matcher→ java.util.regex.Matcher[pattern=(\d{4})-(\d{2})-(\d{2}) region=0,10 lastmatch=] = pattern.matcher(date2026-12-05);if (matcher.matches())
14if (matcher.matches()) {15 System.out.println("Full match: " + matcher.group(0));16 System.out.println("Year: " + matcher.group(1));17 System.out.println("Month: " + matcher.group(2));18 System.out.println("Day: " + matcher.group(3));19}outputFull match: 2026-12-05 Year: 2026 Month: 12 Day: 05email ← user@example.com, emailPattern ← ([^@]+)@([^@]+), emailMatcher ← java.util.regex.Matcher[pattern=([^@]+)@([^@]+) region=0,16 lastmatch=]
21// Email parsing22String email→ user@example.com = "user@example.com";23Pattern emailPattern→ ([^@]+)@([^@]+) = Pattern.compile("([^@]+)@([^@]+)");24Matcher emailMatcher→ java.util.regex.Matcher[pattern=([^@]+)@([^@]+) region=0,16 lastmatch=] = emailPattern.matcher(emailuser@example.com);if (emailMatcher.matches())
26if (emailMatcher.matches()) {27 System.out.println("\nEmail parts:");28 System.out.println("Username: " + emailMatcher.group(1));29 System.out.println("Domain: " + emailMatcher.group(2));30}output Email parts: Username: user Domain: example.comphone ← (555) 123-4567, phonePattern ← \((\d{3})\)\s(\d{3})-(\d{4})
32// Phone number33String phone→ (555) 123-4567 = "(555) 123-4567";34Pattern phonePattern→ \((\d{3})\)\s(\d{3})-(\d{4}) = Pattern.compile("\\((\\d{3})\\)\\s(\\d{3})-(\\d{4})");35Matcher phoneMatcher→ java.util.regex.Matcher[pattern=\((\d{3})\)\s(\d{3})-(\d{4}) region=0,14 lastmatch=] = phonePattern.matcher(phone(555) 123-4567);if (phoneMatcher.matches())
37if (phoneMatcher.matches()) {38 System.out.println("\nPhone parts:");39 System.out.println("Area: " + phoneMatcher.group(1));40 System.out.println("Exchange: " + phoneMatcher.group(2));41 System.out.println("Number: " + phoneMatcher.group(3));42}output Phone parts: Area: 555 Exchange: 123 Number: 4567text ← Call me at 555-1234 or 555-5678, numPattern ← (\d{3})-(\d{4})
44// Multiple matches45String text→ Call me at 555-1234 or 555-5678 = "Call me at 555-1234 or 555-5678";46Pattern numPattern→ (\d{3})-(\d{4}) = Pattern.compile("(\\d{3})-(\\d{4})");47Matcher numMatcher→ java.util.regex.Matcher[pattern=(\d{3})-(\d{4}) region=0,31 lastmatch=] = numPattern.matcher(textCall me at 555-1234 or 555-5678);4849System.out.println("\nAll phone numbers:");50while (numMatcher.find()) {output All phone numbers:while (numMatcher.find())
pass 1 of 249System.out.println("\nAll phone numbers:");50while (numMatcher.find()) {51 System.out.println(" " + numMatcher.group(0) + 52 " (Area: " + numMatcher.group(1) + 53 ", Num: " + numMatcher.group(2) + ")");54}output 555-1234 (Area: 555, Num: 1234)while (numMatcher.find())
pass 2 of 249System.out.println("\nAll phone numbers:");50while (numMatcher.find()) {51 System.out.println(" " + numMatcher.group(0) + 52 " (Area: " + numMatcher.group(1) + 53 ", Num: " + numMatcher.group(2) + ")");54}output 555-5678 (Area: 555, Num: 5678)url ← https://example.com, urlPattern ← (https?)://(.+), urlMatcher ← java.util.regex.Matcher[pattern=(https?)://(.+) region=0,19 lastmatch=]
56// Non-capturing group (?:...)57String url→ https://example.com = "https://example.com";58Pattern urlPattern→ (https?)://(.+) = Pattern.compile("(https?)://(.+)");59Matcher urlMatcher→ java.util.regex.Matcher[pattern=(https?)://(.+) region=0,19 lastmatch=] = urlPattern.matcher(urlhttps://example.com);if (urlMatcher.matches())
61if (urlMatcher.matches()) {62 System.out.println("\nURL parts:");63 System.out.println("Protocol: " + urlMatcher.group(1));64 System.out.println("Domain: " + urlMatcher.group(2));65}output URL parts: Protocol: https Domain: example.com
capturing_group
Parentheses group parts of a pattern and capture matched text for extraction.
Practical Validation
Regex patterns are often used to validate usernames, emails, phone numbers, passwords, URLs, and dates.
Practical.java
Replay: real traced execution (multi-file project)
// Practical validation
import java.util.regex.Pattern;
public class Practical {
public static boolean isValidUsername(String username) {
// 3-16 chars, alphanumeric and underscore, must start with letter
return username.matches("^[a-zA-Z][a-zA-Z0-9_]{2,15}$");
}
public static boolean isValidEmail(String email) {
// Basic email pattern
return email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
}
public static boolean isValidPhone(String phone) {
// Format: (123) 456-7890 or 123-456-7890
return phone.matches("^(\\(\\d{3}\\)\\s?|\\d{3}-)\\d{3}-\\d{4}$");
}
public static boolean isStrongPassword(String password) {
// At least 8 chars, with uppercase, lowercase, and digit
boolean hasLength = password.length() >= 8;
boolean hasUpper = password.matches(".*[A-Z].*");
boolean hasLower = password.matches(".*[a-z].*");
boolean hasDigit = password.matches(".*\\d.*");
return hasLength && hasUpper && hasLower && hasDigit;
}
public static boolean isValidURL(String url) {
return url.matches("^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}.*$");
}
public static boolean isValidDate(String date) {
return date.matches("^\\d{4}-\\d{2}-\\d{2}$");
}
public static void main(String[] args) {
// Usernames
String[] usernames = {"alice", "bob123", "a", "user_name", "123user"};
System.out.println("Usernames:");
for (String user : usernames) {
System.out.println(" " + user + ": " + isValidUsername(user));
}
// Emails
String[] emails = {"user@example.com", "invalid", "test@test.co.uk"};
System.out.println("\nEmails:");
for (String email : emails) {
System.out.println(" " + email + ": " + isValidEmail(email));
}
// Phones
String[] phones = {"(555) 123-4567", "555-123-4567", "5551234567"};
System.out.println("\nPhones:");
for (String phone : phones) {
System.out.println(" " + phone + ": " + isValidPhone(phone));
}
// Passwords
String[] passwords = {"weak", "Strong123", "nodigits", "NOCAPS123"};
System.out.println("\nPasswords:");
for (String pwd : passwords) {
System.out.println(" " + pwd + ": " + isStrongPassword(pwd));
}
// URLs
String[] urls = {"https://example.com", "http://test.org/path", "invalid"};
System.out.println("\nURLs:");
for (String url : urls) {
System.out.println(" " + url + ": " + isValidURL(url));
}
// Dates
String[] dates = {"2025-01-29", "2025-1-9", "01/29/2025"};
System.out.println("\nDates:");
for (String date : dates) {
System.out.println(" " + date + ": " + isValidDate(date));
}
}
}
public static void main(String[] args)
40public static void main(String[] args) {41 // Usernames42 String[] usernames = {"alice", "bob123", "a", "user_name", "123user"};43 System.out.println("Usernames:");44 for (String user : usernames) {outputUsernames:for (String user : usernames)
pass 1 of 543System.out.println("Usernames:");44for (String useralice : usernames) {45 System.out.println(" " + useralice + ": " + isValidUsername(user));46}All 5 passes — pass 1 is the card above pass user1 alice 2 bob123 3 a 4 user_name 5 123user public static boolean isValidUsername(String username)
pass 1 of 57public static boolean isValidUsername(String usernamealice) {8 // 3-16 chars, alphanumeric and underscore, must start with letter9 return username.matches("^[a-zA-Z][a-zA-Z0-9_]{2,15}$");10}All 5 passes — pass 1 is the card above pass username1 alice 2 bob123 3 a 4 user_name 5 123user System.out.println(" " + user + ": " + isValidUsername(user));
44for (String user : usernames) {45 System.out.println(" " + useralice + ": " + isValidUsername(user));46}output alice: trueSystem.out.println(" " + user + ": " + isValidUsername(user));
44for (String user : usernames) {45 System.out.println(" " + userbob123 + ": " + isValidUsername(user));46}output bob123: trueSystem.out.println(" " + user + ": " + isValidUsername(user));
44for (String user : usernames) {45 System.out.println(" " + usera + ": " + isValidUsername(user));46}output a: falseSystem.out.println(" " + user + ": " + isValidUsername(user));
44for (String user : usernames) {45 System.out.println(" " + useruser_name + ": " + isValidUsername(user));46}output user_name: trueSystem.out.println(" " + user + ": " + isValidUsername(user));
44for (String user : usernames) {45 System.out.println(" " + user123user + ": " + isValidUsername(user));46}output 123user: falseString[] emails = {"user@example.com", "invalid", "test@test.co.uk"};
48// Emails49String[] emails = {"user@example.com", "invalid", "test@test.co.uk"};50System.out.println("\nEmails:");51for (String email : emails) {output Emails:for (String email : emails)
pass 1 of 350System.out.println("\nEmails:");51for (String emailuser@example.com : emails) {52 System.out.println(" " + emailuser@example.com + ": " + isValidEmail(email));53}All 3 passes — pass 1 is the card above pass email1 user@example.com 2 invalid 3 test@test.co.uk public static boolean isValidEmail(String email)
pass 1 of 312public static boolean isValidEmail(String emailuser@example.com) {13 // Basic email pattern14 return email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");15}All 3 passes — pass 1 is the card above pass email1 user@example.com 2 invalid 3 test@test.co.uk System.out.println(" " + email + ": " + isValidEmail(email));
51for (String email : emails) {52 System.out.println(" " + emailuser@example.com + ": " + isValidEmail(email));53}output user@example.com: trueSystem.out.println(" " + email + ": " + isValidEmail(email));
51for (String email : emails) {52 System.out.println(" " + emailinvalid + ": " + isValidEmail(email));53}output invalid: falseSystem.out.println(" " + email + ": " + isValidEmail(email));
51for (String email : emails) {52 System.out.println(" " + emailtest@test.co.uk + ": " + isValidEmail(email));53}output test@test.co.uk: trueString[] phones = {"(555) 123-4567", "555-123-4567", "5551234567"};
55// Phones56String[] phones = {"(555) 123-4567", "555-123-4567", "5551234567"};57System.out.println("\nPhones:");58for (String phone : phones) {output Phones:for (String phone : phones)
pass 1 of 357System.out.println("\nPhones:");58for (String phone(555) 123-4567 : phones) {59 System.out.println(" " + phone(555) 123-4567 + ": " + isValidPhone(phone));60}All 3 passes — pass 1 is the card above pass phone1 (555) 123-4567 2 555-123-4567 3 5551234567 public static boolean isValidPhone(String phone)
pass 1 of 317public static boolean isValidPhone(String phone(555) 123-4567) {18 // Format: (123) 456-7890 or 123-456-789019 return phone.matches("^(\\(\\d{3}\\)\\s?|\\d{3}-)\\d{3}-\\d{4}$");20}All 3 passes — pass 1 is the card above pass phone1 (555) 123-4567 2 555-123-4567 3 5551234567 System.out.println(" " + phone + ": " + isValidPhone(phone));
58for (String phone : phones) {59 System.out.println(" " + phone(555) 123-4567 + ": " + isValidPhone(phone));60}output (555) 123-4567: trueSystem.out.println(" " + phone + ": " + isValidPhone(phone));
58for (String phone : phones) {59 System.out.println(" " + phone555-123-4567 + ": " + isValidPhone(phone));60}output 555-123-4567: trueSystem.out.println(" " + phone + ": " + isValidPhone(phone));
58for (String phone : phones) {59 System.out.println(" " + phone5551234567 + ": " + isValidPhone(phone));60}output 5551234567: falseString[] passwords = {"weak", "Strong123", "nodigits", "NOCAPS123"};
62// Passwords63String[] passwords = {"weak", "Strong123", "nodigits", "NOCAPS123"};64System.out.println("\nPasswords:");65for (String pwd : passwords) {output Passwords:for (String pwd : passwords)
pass 1 of 464System.out.println("\nPasswords:");65for (String pwdweak : passwords) {66 System.out.println(" " + pwdweak + ": " + isStrongPassword(pwd));67}All 4 passes — pass 1 is the card above pass pwd1 weak 2 Strong123 3 nodigits 4 NOCAPS123 hasLength ← false, hasUpper ← false, hasLower ← true, hasDigit ← false
pass 1 of 422public static boolean isStrongPassword(String passwordweak) {23 // At least 8 chars, with uppercase, lowercase, and digit24 boolean hasLength→ false = password.length() >= 8;25 boolean hasUpper→ false = password.matches(".*[A-Z].*");26 boolean hasLower→ true = password.matches(".*[a-z].*");27 boolean hasDigit→ false = password.matches(".*\\d.*");2829 return hasLengthfalse && hasUpperfalse && hasLowertrue && hasDigitfalse;30}All 4 passes — pass 1 is the card above pass passwordhasLengthhasUpperhasLowerhasDigit1 weak false false true false 2 Strong123 true true true true 3 nodigits true false true false 4 NOCAPS123 true true false true System.out.println(" " + pwd + ": " + isStrongPassword(pwd));
65for (String pwd : passwords) {66 System.out.println(" " + pwdweak + ": " + isStrongPassword(pwd));67}output weak: falseSystem.out.println(" " + pwd + ": " + isStrongPassword(pwd));
65for (String pwd : passwords) {66 System.out.println(" " + pwdStrong123 + ": " + isStrongPassword(pwd));67}output Strong123: trueSystem.out.println(" " + pwd + ": " + isStrongPassword(pwd));
65for (String pwd : passwords) {66 System.out.println(" " + pwdnodigits + ": " + isStrongPassword(pwd));67}output nodigits: falseSystem.out.println(" " + pwd + ": " + isStrongPassword(pwd));
65for (String pwd : passwords) {66 System.out.println(" " + pwdNOCAPS123 + ": " + isStrongPassword(pwd));67}output NOCAPS123: falseString[] urls = {"https://example.com", "http://test.org/path", "inval…
69// URLs70String[] urls = {"https://example.com", "http://test.org/path", "invalid"};71System.out.println("\nURLs:");72for (String url : urls) {output URLs:for (String url : urls)
pass 1 of 371System.out.println("\nURLs:");72for (String urlhttps://example.com : urls) {73 System.out.println(" " + urlhttps://example.com + ": " + isValidURL(url));74}All 3 passes — pass 1 is the card above pass url1 https://example.com 2 http://test.org/path 3 invalid public static boolean isValidURL(String url)
pass 1 of 332public static boolean isValidURL(String urlhttps://example.com) {33 return url.matches("^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}.*$");34}All 3 passes — pass 1 is the card above pass url1 https://example.com 2 http://test.org/path 3 invalid System.out.println(" " + url + ": " + isValidURL(url));
72for (String url : urls) {73 System.out.println(" " + urlhttps://example.com + ": " + isValidURL(url));74}output https://example.com: trueSystem.out.println(" " + url + ": " + isValidURL(url));
72for (String url : urls) {73 System.out.println(" " + urlhttp://test.org/path + ": " + isValidURL(url));74}output http://test.org/path: trueSystem.out.println(" " + url + ": " + isValidURL(url));
72for (String url : urls) {73 System.out.println(" " + urlinvalid + ": " + isValidURL(url));74}output invalid: falseString[] dates = {"2025-01-29", "2025-1-9", "01/29/2025"};
76// Dates77String[] dates = {"2025-01-29", "2025-1-9", "01/29/2025"};78System.out.println("\nDates:");79for (String date : dates) {output Dates:for (String date : dates)
pass 1 of 378System.out.println("\nDates:");79for (String date2025-01-29 : dates) {80 System.out.println(" " + date2025-01-29 + ": " + isValidDate(date));81}All 3 passes — pass 1 is the card above pass date1 2025-01-29 2 2025-1-9 3 01/29/2025 public static boolean isValidDate(String date)
pass 1 of 336public static boolean isValidDate(String date2025-01-29) {37 return date.matches("^\\d{4}-\\d{2}-\\d{2}$");38}All 3 passes — pass 1 is the card above pass date1 2025-01-29 2 2025-1-9 3 01/29/2025 System.out.println(" " + date + ": " + isValidDate(date));
79for (String date : dates) {80 System.out.println(" " + date2025-01-29 + ": " + isValidDate(date));81}output 2025-01-29: trueSystem.out.println(" " + date + ": " + isValidDate(date));
79for (String date : dates) {80 System.out.println(" " + date2025-1-9 + ": " + isValidDate(date));81}output 2025-1-9: falseSystem.out.println(" " + date + ": " + isValidDate(date));
79for (String date : dates) {80 System.out.println(" " + date01/29/2025 + ": " + isValidDate(date));81}output 01/29/2025: false
Exercise: Practical.java
Validate that a username contains only letters, numbers, and underscores, and is 3-16 characters long