Java Regex to Match Greek Characters (Script vs Block)

Match Greek characters in a Java regex with \p{IsGreek} for the script or \p{InGreek} and \p{InGreekExtended} for blocks, plus accents and case.

Java regex greek script vs block

In Java regex, \p{IsGreek} matches any character of the Greek script, wherever Unicode stores it, while \p{InGreek} and \p{InGreekExtended} match characters by their position in a Unicode block. A script is a writing system, such as Greek or Latin. A block is a fixed range of code points, such as U+0370 to U+03FF. The two ideas overlap but are not the same, and when we match Greek characters, the difference decides whether a Coptic letter, a Greek question mark or an ancient Greek number passes the check.

We use these properties to find Greek letters in mixed text, to accept a Greek name in a form field, or to check that a font covers a code point range. Greek characters in the code are written as Java escapes. For example, \u03b1 is the small letter alpha, \u1f00 is alpha with a breathing mark from the Greek Extended block, and \u03e2 is the Coptic letter shei.

The following example tests three characters against the script property and the two block properties.

boolean alphaScript = "\u03b1".matches("\\p{IsGreek}");                   // true, script
boolean psiliScript = "\u1f00".matches("\\p{IsGreek}");                   // true
boolean alphaBlock = "\u03b1".matches("\\p{InGreek}");                    // true, block U+0370..U+03FF
boolean psiliBlock = "\u1f00".matches("\\p{InGreek}");                    // false
boolean psiliExtended = "\u1f00".matches("\\p{InGreekExtended}");         // true, block U+1F00..U+1FFF
boolean sheiBlock = "\u03e2".matches("\\p{InGreek}");                     // true, Coptic letter
boolean sheiScript = "\u03e2".matches("\\p{IsGreek}");                    // false
boolean alphaRanges = "\u03b1".matches("[\\u0370-\\u03FF\\u1F00-\\u1FFF]"); // true, both blocks as ranges

Notice that the Coptic letter passes the block check and fails the script check. We start with a search in mixed text, compare script and block in a table, cover the Greek Extended block, the property names Java accepts, and accents and letter case in Greek words. The Java regex guide covers the Pattern basics these examples build on.

1. How to Match Greek Characters in a String

For most tasks, a Greek character means a Greek letter or a Greek sign, so the script property \p{IsGreek} is the right default. The method Matcher.results() returns each match together with its position, which replaces the usual while (matcher.find()) loop.

For example, a math quiz app stores formulas such as a + b = \u03b1 + \u03b2 and must highlight every Greek symbol in the rendered question.

Pattern greek = Pattern.compile("\\p{IsGreek}");
String formula = "a + b = \u03b1 + \u03b2";

List<Integer> starts = greek.matcher(formula).results().map(MatchResult::start).toList();   // [8, 12]
long count = greek.matcher(formula).results().count();                                      // 2
boolean hasGreek = greek.matcher(formula).find();                                           // true
boolean plainText = greek.matcher("hello").find();                                          // false

The start() index counts char values from 0, and end() is one position after the match. To get the letters themselves, we map each result with MatchResult::group.

2. Greek Script vs Greek Block

Unicode assigns every character to one block (by its code point range) and to one script (by the writing system it belongs to). Java exposes both, and each property has several spellings.

  • \p{IsGreek}, also written \p{script=Greek}, \p{sc=Greek} or \p{IsGrek}, tests the script, the same as Character.UnicodeScript.of(c) == GREEK.
  • \p{InGreek}, also written \p{block=Greek} or \p{InGreekandCoptic}, tests the block named Greek and Coptic, U+0370 to U+03FF.
  • \p{InGreekExtended} tests the Greek Extended block, U+1F00 to U+1FFF.
Diagram of the Greek and Coptic block, the Greek Extended block and the Greek script with example characters in each area
\p{IsGreek} follows the script across blocks, while \p{InGreek} also accepts Coptic letters and unassigned code points

The block Greek and Coptic is not all Greek, because it holds 14 Coptic letters, some common punctuation and unassigned code points, 27 code points in total that are not in the Greek script. In the other direction, Java 25 knows 518 Greek-script code points, and 168 of them are outside both Greek blocks, such as phonetic letters, the Ohm sign and the Ancient Greek Numbers block.

CharacterBlockScript\p{InGreek}\p{IsGreek}
Small alpha, U+03B1Greek and CopticGreektruetrue
Coptic shei, U+03E2Greek and CopticCoptictruefalse
Greek question mark, U+037EGreek and CopticCommontruefalse
Unassigned, U+0378Greek and CopticUnknowntruefalse
Alpha with psili, U+1F00Greek ExtendedGreekfalsetrue
Ohm sign, U+2126Letterlike SymbolsGreekfalsetrue
Ancient Greek numeral, U+10140Ancient Greek NumbersGreekfalsetrue
Micro sign, U+00B5Latin-1 SupplementCommonfalsefalse

The Character class answers the same questions in plain Java code, which helps when a check is not part of a larger regex. Java 25 implements Unicode 16.0, so the script and block data match that version.

Character.UnicodeBlock block = Character.UnicodeBlock.of(0x03e2);      // GREEK
Character.UnicodeScript script = Character.UnicodeScript.of(0x03e2);   // COPTIC

The constant GREEK is the name Java uses for the Greek and Coptic block. We use the block properties only when the requirement names a code point range, for example a font that covers the Greek and Coptic block, or a data format that allows only those code points. For questions about the language or the alphabet, the script is the correct property.

3. Matching the Greek Extended Block

The Greek Extended block holds precomposed letters for polytonic Greek, the accent and breathing system used for Ancient Greek and in Modern Greek before 1982. Each character combines a base letter with one or more marks, such as small alpha with psili (U+1F00) or capital omega with psili and prosgegrammeni (U+1FA8).

A digital library that publishes Ancient Greek texts is a typical user of this block, because a check for polytonic letters tells it which documents need a font with full Greek Extended support.

Pattern extended = Pattern.compile("\\p{InGreekExtended}");

List<Integer> positions = extended.matcher("\u1fb2 \u1fa8").results().map(MatchResult::start).toList();   // [0, 2]
boolean inBasicBlock = "\u1f00".matches("\\p{InGreek}");                     // false
boolean inExtended = "\u03b1".matches("\\p{InGreekExtended}");               // false
boolean eitherBlock = "\u1f00".matches("[\\p{InGreek}\\p{InGreekExtended}]"); // true, either block

The old range form, [\u0370-\u03FF\u1F00-\u1FFF], is the same as combining the two block properties in one class. The Greek Extended block also contains 23 unassigned code points. The script property \p{IsGreek} covers the Greek letters of both blocks and leaves out Coptic letters and unassigned code points, so it is the better choice even for polytonic text.

4. Property Names Java Accepts and Rejects

Java is strict about the spelling of these names, and a wrong name fails when the pattern is compiled. The rules differ from Perl and PCRE, so a pattern copied from a PHP project can break.

  • The script needs the Is prefix or script= or sc=. The name \p{Greek}, which works in Perl and PCRE (PHP), throws an exception in Java.
  • The block needs the In prefix or block= or blk=. The name may be written without spaces (GreekExtended), with underscores (Greek_Extended), or as the short Java name Greek for the Greek and Coptic block.
  • Underscores do not work in every block name. The name \p{InGreek_and_Coptic} is rejected, while \p{InGreekandCoptic} is accepted.
  • The prefixes are case-sensitive, so \p{IsGREEK} works and \p{isgreek} does not.
boolean byScript = Pattern.matches("\\p{script=Greek}", "\u03b1");          // true
boolean byCode = Pattern.matches("\\p{IsGrek}", "\u03b1");                   // true, four-letter script code
boolean byBlock = Pattern.matches("\\p{block=Greek}", "\u03b1");             // true
boolean underscores = Pattern.matches("\\p{InGreek_Extended}", "\u1f00");    // true
Pattern perlStyle = Pattern.compile("\\p{Greek}");                           // PatternSyntaxException

The exception message for the last line names the property and points to its position.

java.util.regex.PatternSyntaxException: Unknown character property name {Greek} near index 8
\p{Greek}
        ^

5. Greek Words, Accents and Case

Modern Greek uses the tonos accent, as in the word kalimera (good morning), whose sixth letter is epsilon with tonos (U+03AD). In the precomposed form (NFC), that letter is one Greek-script character. In the decomposed form (NFD), it is a plain epsilon followed by the combining acute accent U+0301, and combining marks belong to the script Inherited, not to Greek. A pattern like \p{IsGreek}+ stops at the accent in that case.

String kalimera = "\u039a\u03b1\u03bb\u03b7\u03bc\u03ad\u03c1\u03b1";
String decomposed = Normalizer.normalize(kalimera, Normalizer.Form.NFD);

boolean composedOk = kalimera.matches("\\p{IsGreek}+");                // true
boolean decomposedOk = decomposed.matches("\\p{IsGreek}+");            // false
boolean withMarks = decomposed.matches("[\\p{IsGreek}\\p{M}]+");       // true, letters plus marks

Adding \p{M} (any mark) to the class makes the pattern work for both forms. Text from macOS file names and some keyboards arrives decomposed, so a Greek name field that rejects it looks broken to the user. The same class extracts Greek words from mixed text.

Pattern greekWord = Pattern.compile("[\\p{IsGreek}\\p{M}]+");
String mixed = "Hello \u039a\u03b1\u03bb\u03b7\u03bc\u03ad\u03c1\u03b1 and \u03b1\u03b2\u03b3!";

List<Integer> wordLengths = greekWord.matcher(mixed).results().map(r -> r.group().length()).toList();   // [8, 3]

For case-insensitive matching, the (?i) flag alone compares only ASCII letters in Java. Greek capital alpha (U+0391) does not match small alpha until we also turn on Unicode case folding with (?iu) or Pattern.UNICODE_CASE. With Unicode case folding, capital sigma also matches the final sigma U+03C2, which Greek writes at the end of a word.

boolean asciiOnly = Pattern.matches("(?i)\\u03b1", "\u0391");          // false
boolean unicodeCase = Pattern.matches("(?iu)\\u03b1", "\u0391");       // true
boolean byFlags = Pattern.compile("\u03b1", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher("\u0391").matches();   // true
boolean finalSigma = Pattern.matches("(?iu)\\u03a3", "\u03c2");        // true, final sigma

Two lookalike characters cause bugs in data cleanup. The Ohm sign U+2126 is in the Greek script but not in the Greek block, and Unicode normalization (NFC) replaces it with capital omega U+03A9. The micro sign U+00B5 is in neither, and only the compatibility form NFKC turns it into small mu U+03BC. When input can contain them, we normalize first, and the article on cleaning non-ASCII text covers the Normalizer class.

String ohm = Normalizer.normalize("\u2126", Normalizer.Form.NFC);      // capital omega
boolean ohmIsOmega = ohm.equals("\u03a9");                              // true
boolean microIsMu = Normalizer.normalize("\u00b5", Normalizer.Form.NFKC).equals("\u03bc");   // true

6. Example Project

The project on GitHub runs every snippet on this page and prints Greek characters as escapes, so the output is readable on any console. Its JUnit 6 tests also walk through all Unicode code points to confirm the counts in section 2. It needs Java 25 and Maven.

mvn -q compile exec:java
mvn test

7. Greek Regex FAQs

Greek text in forms and search features mostly raises questions about accents and about what \w accepts.

7.1. Does \w Match Greek Letters in Java?

No, not by default. The class \w covers only [a-zA-Z_0-9], so a Greek word fails. With the UNICODE_CHARACTER_CLASS flag, written (?U), \w follows Unicode rules and accepts Greek letters too, along with letters of every other script.

boolean asciiWord = "\u03b1\u03b2".matches("\\w+");               // false
boolean unicodeWord = "\u03b1\u03b2".matches("(?U)\\w+");         // true

7.2. How Do We Check That a Whole String Is Greek?

We call matches() with a pattern that allows Greek letters, marks and the separators we expect. The method matches() succeeds only when the whole input fits, so one Latin letter makes it fail.

Pattern greekName = Pattern.compile("[\\p{IsGreek}\\p{M} ]+");
boolean onlyGreek = greekName.matcher("\u039d\u03af\u03ba\u03bf\u03c2").matches();   // true
boolean mixedName = greekName.matcher("Nikos \u039d").matches();                     // false

7.3. How Do We Remove Greek Accents With a Regex?

We decompose the text with NFD and delete the marks with \p{M}. Search features use this so that a query without tonos still finds the accented word.

String plain = Normalizer.normalize("\u03ad", Normalizer.Form.NFD).replaceAll("\\p{M}", "");   // plain epsilon
boolean isEpsilon = plain.equals("\u03b5");                                                       // true

7.4. Does \p{IsGreek} Match Coptic Letters?

No. Since Unicode 4.1, Coptic is a separate script, so the Coptic letters in the Greek and Coptic block belong to the script Coptic. To accept both, we combine the two properties in one class.

boolean sheiGreek = "\u03e2".matches("\\p{IsGreek}");                     // false
boolean sheiEither = "\u03e2".matches("[\\p{IsGreek}\\p{IsCoptic}]");     // true

8. Conclusion

The property \p{IsGreek} matches the Greek script, which means every Greek letter and sign in any block, and nothing from Coptic or unassigned code points. The properties \p{InGreek} and \p{InGreekExtended} match the Greek and Coptic block (U+0370 to U+03FF) and the Greek Extended block (U+1F00 to U+1FFF) by position only.

For whole words, we add \p{M} so decomposed accents do not split a word. For case-insensitive matching, we use (?iu), because (?i) alone ignores Greek letters.

9. References

Happy Learning !!

Source Code on Github

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.