Skip to content
Back to skills

Js Regex Cjk Word Boundary

ASecurity

Fix JavaScript regex failures when matching CJK (Chinese/Japanese/Korean) text using \b word boundaries. Use when: (1) Regex pattern with \b silently fails to match Japanese, Chinese, or Korean text, (2) Pattern works for Latin/ASCII text but not CJK, (3) hasDriverLicenceCue or similar text-detection function returns false for CJK input despite correct characters, (4) inferIssuerFromTitleText or pattern-matching functions fail on non-Latin scripts. Root cause: JavaScript \b only recognizes [a...

  • 265 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added May 27, 2026
developmentjavascriptjavaexpressdebugginggit

Works with

  • claude code

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add divinevideo/divine-mobile --skill js-regex-cjk-word-boundary --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Js Regex Cjk Word Boundary?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Js Regex Cjk Word Boundary
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/divinevideo-js-regex-cjk-word-boundary/badge)](https://www.skillsdirectory.com/skills/divinevideo-js-regex-cjk-word-boundary)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: js-regex-cjk-word-boundary
description: |
  Fix JavaScript regex failures when matching CJK (Chinese/Japanese/Korean) text using \b word
  boundaries. Use when: (1) Regex pattern with \b silently fails to match Japanese, Chinese, or
  Korean text, (2) Pattern works for Latin/ASCII text but not CJK, (3) hasDriverLicenceCue or
  similar text-detection function returns false for CJK input despite correct characters,
  (4) inferIssuerFromTitleText or pattern-matching functions fail on non-Latin scripts.
  Root cause: JavaScript \b only recognizes [a-zA-Z0-9_] as "word characters" — CJK characters
  are classified as \W (non-word), so \b before/after CJK always sees a non-word/non-word
  boundary and fails to match.
author: Claude Code
version: 1.0.0
date: 2026-03-09
---

# JavaScript Regex: \b Word Boundary Fails with CJK Characters

## Problem

JavaScript's `\b` (word boundary) assertion silently fails when used with CJK
(Chinese/Japanese/Korean) characters. The regex compiles without error and runs without
throwing, but it simply never matches CJK text that should match. This is particularly
insidious because:

1. No error is thrown — the regex just returns `false`
2. The same pattern works perfectly for Latin/ASCII text
3. The CJK characters in the pattern are correct (verified by direct string comparison)

## Context / Trigger Conditions

- Regex pattern like `/\b\u904B\u8EE2\u514D\u8A31\u8A3C\b/` (Japanese: 運転免許証) returns `false`
  on text containing the exact characters
- Pattern like `/\b\uC6B4\uC804\uBA74\uD5C8\uC99D\b/` (Korean: 운전면허증) fails similarly
- Text-detection functions (e.g., `hasDriverLicenceCue()`, `inferIssuerFromTitleText()`) return
  incorrect results for CJK input while working correctly for all Latin-script patterns
- Any regex using `\b` boundaries around non-ASCII Unicode characters (also affects Cyrillic,
  Arabic, Thai, etc.)

## Root Cause

JavaScript's `\b` matches the boundary between a "word character" (`\w` = `[a-zA-Z0-9_]`) and
a "non-word character" (`\W`). CJK characters are classified as `\W` (non-word characters).

When `\b` appears before a CJK character, it looks for a `\w`-to-`\W` or `\W`-to-`\w`
transition. But if the preceding character is also `\W` (whitespace, punctuation, start of
string, or another CJK character), the boundary condition is `\W`-to-`\W`, which `\b` does
NOT match.

```javascript
// This FAILS — \b doesn't work with CJK
/\b\u904B\u8EE2\u514D\u8A31\u8A3C\b/.test("運転免許証")  // false!

// This WORKS — no word boundaries
/\u904B\u8EE2\u514D\u8A31\u8A3C/.test("運転免許証")  // true
```

## Solution

### Quick Fix: Remove `\b` from CJK patterns

Simply remove `\b` assertions from any regex pattern that matches CJK characters:

```javascript
// Before (broken):
[/\b\u904B\u8EE2\u514D\u8A31\u8A3C\b/, "JAPAN"],      // 運転免許証
[/\b\uC6B4\uC804\uBA74\uD5C8\uC99D\b/, "KOREA"],      // 운전면허증

// After (working):
[/\u904B\u8EE2\u514D\u8A31\u8A3C/, "JAPAN"],            // 運転免許証
[/\uC6B4\uC804\uBA74\uD5C8\uC99D/, "KOREA"],           // 운전면허증
```

### Better Fix: Use Unicode-aware boundaries (if available)

For environments supporting the `v` flag (ES2024+), you can use Unicode property escapes:

```javascript
// Unicode-aware approach (requires /v flag support):
/(?<=^|[\s\p{P}])\u904B\u8EE2\u514D\u8A31\u8A3C(?=$|[\s\p{P}])/v
```

### Alternative: Manual boundary with lookbehind/lookahead

```javascript
// Manual boundary that works with CJK:
/(?<!\p{L})\u904B\u8EE2\u514D\u8A31\u8A3C(?!\p{L})/u
```

### For mixed Latin/CJK pattern arrays

When you have an array of patterns where some are Latin and some are CJK, use `\b` only for
Latin patterns:

```javascript
const patterns = [
  [/\bDRIVER'?S?\s+LICEN[CS]E\b/, "match"],   // Latin — \b works
  [/\bFÜHRERSCHEIN\b/, "match"],               // Latin+diacritics — \b works (Ü is \W but context helps)
  [/\u904B\u8EE2\u514D\u8A31\u8A3C/, "match"], // CJK — no \b needed
  [/\uC6B4\uC804\uBA74\uD5C8\uC99D/, "match"], // CJK — no \b needed
];
```

## Verification

```javascript
// Test that CJK matching works:
console.log(/\u904B\u8EE2\u514D\u8A31\u8A3C/.test("運転免許証"));  // true
console.log(/\uC6B4\uC804\uBA74\uD5C8\uC99D/.test("운전면허증"));  // true

// Verify it doesn't false-match substrings you don't want:
console.log(/\u904B\u8EE2\u514D\u8A31\u8A3C/.test("別の運転免許証テスト"));  // true (substring match is usually fine for CJK)
```

## Example

Real-world case from a document-type detection function:

```javascript
function hasDriverLicenceCue(text) {
  const combined = text.toUpperCase();
  return (
    /\bDRIVER'?S?\s+LICEN[CS]E\b/.test(combined) ||   // English
    /\bFÜHRERSCHEIN\b/.test(combined) ||               // German
    /\bPERMIS DE CONDUIRE\b/.test(combined) ||          // French
    /\u904B\u8EE2\u514D\u8A31\u8A3C/.test(combined) || // Japanese (no \b!)
    /\uC6B4\uC804\uBA74\uD5C8\uC99D/.test(combined)    // Korean (no \b!)
  );
}
```

## Notes

- This affects ALL non-ASCII Unicode scripts, not just CJK: Cyrillic, Arabic, Thai, Devanagari, etc.
- The `u` (unicode) flag does NOT fix this — `\b` behavior with `\w`/`\W` is unchanged.
- Removing `\b` from CJK patterns is generally safe because CJK characters are unlikely to
  appear as substrings within other words in unrelated contexts.
- The `regexp-cjk` npm package provides CJK-aware regex utilities if you need more sophisticated matching.
- When debugging: if a regex works for "DRIVER'S LICENCE" but not "運転免許証", suspect `\b` first.

## References

- [MDN: Word boundary assertion \b](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Word_boundary_assertion)
- [TC39 Issue #1020: Regexp with word boundaries do not match cyrillic string](https://github.com/tc39/ecma262/issues/1020)
- [Word boundaries in JavaScript's regular expressions with UTF-8 strings](https://breakthebit.org/post/3446894238/word-boundaries-in-javascripts-regular)
- [regexp-cjk npm package](https://www.npmjs.com/package/regexp-cjk)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.