# How to Use Guava CharMatcher for Character Filtering and Matching: A Complete Guide

> Master Guava CharMatcher for efficient character filtering and matching. This guide offers a fluent API and practical examples for seamless text processing.

- Repository: [Google/guava](https://github.com/google/guava)
- Tags: how-to-guide
- Published: 2026-08-08

---

**Guava's `CharMatcher` is an immutable predicate that provides a fluent API for matching, filtering, and transforming characters via factory methods, logical combinators, and pre-computed optimizations.**

The `CharMatcher` class in Google's Guava library (`google/guava`) eliminates boilerplate when processing text by offering a rich set of utilities for character-level operations. Unlike regular expressions that operate on strings, `CharMatcher` works directly on primitive `char` values, making it ideal for high-performance text sanitization, validation, and extraction tasks. The implementation resides in [`guava/src/com/google/common/base/CharMatcher.java`](https://github.com/google/guava/blob/main/guava/src/com/google/common/base/CharMatcher.java), with comprehensive usage patterns demonstrated in [`guava-tests/test/com/google/common/base/CharMatcherTest.java`](https://github.com/google/guava/blob/main/guava-tests/test/com/google/common/base/CharMatcherTest.java).

## Creating CharMatcher Instances with Factory Methods

`CharMatcher` provides static factory methods that return specialized implementations for common character sets. Each factory returns a concrete subclass optimized for its specific matching logic, such as `Any`, `None`, `Is`, or `InRange`.

- **`any()`** and **`none()`**: Match all or no characters respectively.
- **`is(char match)`**: Matches exactly one specific character.
- **`inRange(char start, char end)`**: Matches any character within a continuous range.
- **`anyOf(CharSequence chars)`**: Matches any character present in the given sequence.
- **`digit()`**, **`javaLetter()`**, **`whitespace()`**: Predefined matchers for common Unicode categories.

```java
// Match specific characters
CharMatcher digit = CharMatcher.digit();               // Any Unicode digit
CharMatcher hexLower = CharMatcher.inRange('a', 'f');  // a through f
CharMatcher vowels = CharMatcher.anyOf("aeiouAEIOU");  // Any vowel

```

## Composing Matchers with Logical Combinators

Complex matching logic is built using **`and()`**, **`or()`**, and **`negate()`** methods. These return composite instances (`And`, `Or`, `Negated` classes) that delegate `matches(char)` calls to their component matchers.

```java
// Build a matcher for ASCII letters or digits, then negate it
CharMatcher notLetterOrDigit = CharMatcher.ascii()
    .and(CharMatcher.inRange('a', 'z')
        .or(CharMatcher.inRange('A', 'Z'))
        .or(CharMatcher.inRange('0', '9')))
    .negate();

// Hexadecimal matcher combining ranges
CharMatcher hex = CharMatcher.inRange('0', '9')
    .or(CharMatcher.inRange('a', 'f'))
    .or(CharMatcher.inRange('A', 'F'));

System.out.println(hex.matches('B')); // true

```

## Text Processing with Utility Methods

`CharMatcher` provides text-processing methods that operate directly on `CharSequence` without manual looping. These implementations use `indexIn` internally to locate the first match, then process the remainder efficiently.

**Removing unwanted characters:**

```java
String raw = "User_123!@#";
String cleaned = CharMatcher.anyOf("!@#").removeFrom(raw);  // "User_123"

```

**Retaining only matching characters:**

```java
String source = "a1b2c3";
String letters = CharMatcher.inRange('a', 'z').retainFrom(source);  // "abc"

```

**Trimming and collapsing:**

```java
String messy = "\t  Hello   World  \n";
String tidy = CharMatcher.whitespace()
    .trimAndCollapseFrom(messy, ' ');   // "Hello World"

```

**Replacing characters:**

```java
String result = CharMatcher.digit().replaceFrom("a1b2c3", '*');  // "a*b*c*"

```

## Optimizing Performance with Pre-computation

For matchers used extensively in tight loops, call **`precomputed()`** to generate a fast lookup structure. According to the Guava source code, this invokes `Platform.precomputeCharMatcher(this)`, which internally calls `precomputedInternal()` to select between `SmallCharMatcher`, `BitSetMatcher`, or a negated fast matcher based on the character set size.

```java
CharMatcher fastMatcher = CharMatcher.anyOf("aeiou").precomputed();

```

The **`FastMatcher`** and **`NamedFastMatcher`** classes in the hierarchy indicate matchers that are already optimized. These subclasses override `precomputed()` to return `this`, bypassing redundant optimization.

## Unicode and Supplementary Characters

`CharMatcher` operates exclusively on Basic Multilingual Plane (BMP) values. Supplementary Unicode characters (code points above U+FFFF) are treated as surrogate pairs, with each surrogate counted and matched separately in methods like `countIn` and `matches(char)`.

## Summary

- **Factory methods** like `anyOf()`, `inRange()`, and `digit()` create specialized matcher instances in [`CharMatcher.java`](https://github.com/google/guava/blob/main/CharMatcher.java).
- **Logical combinators** (`and()`, `or()`, `negate()`) compose simple matchers into complex predicates using delegate classes.
- **Text-processing methods** (`removeFrom`, `retainFrom`, `trimAndCollapseFrom`) provide one-line solutions for common string sanitization tasks.
- **Pre-computation** via `precomputed()` builds compact `BitSet` or hash table structures for constant-time `matches(char)` lookups.
- **BMP limitation**: `CharMatcher` handles supplementary Unicode characters as individual surrogate pairs rather than single code points.

## Frequently Asked Questions

### How does CharMatcher differ from Java's regular expressions?

`CharMatcher` operates on individual primitive `char` values rather than string patterns, providing better performance for single-character classification and offering specialized text-processing methods (`collapseFrom`, `trimAndCollapseFrom`) that would require complex regex replacement logic. Unlike `Pattern` and `Matcher`, `CharMatcher` instances are immutable and thread-safe by design, allowing reuse across multiple threads without synchronization.

### When should I call precomputed() on a CharMatcher?

Call `precomputed()` when you will use the same `CharMatcher` instance repeatedly in performance-critical code paths, such as processing large files or high-throughput data streams. The optimization builds a compact `BitSet` or hash table that reduces `matches(char)` lookup time from predicate evaluation to constant-time array access. Simple matchers returned by `any()`, `none()`, or `is()` already extend `FastMatcher` and automatically bypass pre-computation.

### How do I create a custom CharMatcher for a specific predicate?

Use **`CharMatcher.forPredicate(Predicate<? super Character> predicate)`** to wrap a custom condition, or subclass `CharMatcher` directly and override the **`matches(char c)`** method. When subclassing, consider also overriding `toString()` for debugging and extending `NamedFastMatcher` if your implementation is inherently fast and should skip pre-computation optimization.

### Does CharMatcher support Unicode emoji or supplementary characters?

No, `CharMatcher` only processes 16-bit `char` values from the Basic Multilingual Plane. Supplementary characters such as emoji (code points U+10000 and above) are represented as surrogate pairs in Java, and `CharMatcher` treats each surrogate as an independent character. For example, `countIn()` will return 2 for a single emoji character. Use Java's `CodePoint` APIs or `IntStream` for proper supplementary character handling when working with characters outside the BMP.