Skip to content
cccskills
FreePublished on GitHub

js-regex-cjk-word-boundary

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.

The English summary is being prepared. Showing the original description.

Run score Not tested

See how to install

Files included (1)

  • SKILL.md6.0 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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.

// 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:

// 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:

// 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

// 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:

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

// 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:

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

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y". Use when: (1) ExternalSecret shows OutOfSync in ArgoCD but won't sync, (2) ArgoCD application status shows "namespace X is not permitted in project 'infrastructure'", (3) ExternalSecret targets a namespace managed by a different ArgoCD project, (4) Using apps-of-apps pattern with separate infrastructure and application projects.

The English summary is being prepared. Showing the original description.

divinevideo/divine-mobile265Updated Oct 23, 2026

Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language. After selection, generates AI image prompts and visual briefs section-by-section. Use when the user shares content and needs visual direction, image sourcing, or creative direction for any material.

The English summary is being prepared. Showing the original description.

divinevideo/divine-mobile265Updated Oct 23, 2026

Fix "Null check operator used on a null value" errors when an object is set to null during an async await. Use when: (1) Object reference is nullified while awaiting, (2) Code accesses object with ! after await returns, (3) Cancel/dispose operations run concurrently with async operations on same object. Solution: capture local reference before await.

The English summary is being prepared. Showing the original description.

divinevideo/divine-mobile265Updated Oct 23, 2026

Add custom metadata headers (x-amz-meta-*) to AWS v4 signed requests for GCS S3-compatible API. Use when: (1) Adding custom metadata to GCS uploads via S3 API, (2) Getting signature mismatch errors after adding new headers, (3) x-amz-meta-* headers being ignored or causing 403 errors. Custom headers MUST be included in canonical headers and signed headers list.

The English summary is being prepared. Showing the original description.

divinevideo/divine-mobile265Updated Oct 23, 2026

Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings. Use when: (1) Password authentication fails with correct password, (2) Secret created with `<<< "value"` syntax, (3) Error like "password authentication failed" or "invalid token" despite correct value. Bash here-strings (`<<<`) add a trailing newline that corrupts secrets.

The English summary is being prepared. Showing the original description.

divinevideo/divine-mobile265Updated Oct 23, 2026

Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp). Use when: (1) Media moderation, transcoding, or analysis silently skips files from Blossom or content-addressed storage servers, (2) URL extraction from Nostr event tags (imeta, r tags) drops URLs without recognized extensions, (3) CDN fallback URLs append .mp4 but the actual server uses extensionless content-addressed paths like /{sha256}. Common in Nostr video events (kind 34236) where different clients use different URL formats.

The English summary is being prepared. Showing the original description.

divinevideo/divine-mobile265Updated Oct 23, 2026

See all skills by divinevideo

Report a problem with this skill