[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6MVPXK1BX0QCSC6DCBY81TR":3,"skill-same:01M6MVPXK1BX0QCSC6DCBY81TR":85},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":57,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":6,"ownerHtmlUrl":62,"ownerBlogUrl":6,"ownerDescription":63,"updatedAt":64,"install":65,"resources":78},"01M6MVPXK1BX0QCSC6DCBY81TR","regex-patterns",null,"Practical regex patterns across languages and use cases. Use when validating input (email, URL, IP), parsing log lines, extracting data from text, refactoring code with search-and-replace, or debugging why a regex doesn't match.","Kernel8901\u002Fai-agent-skills-classification","Kernel8901","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F72647553?v=4","01M6KV388J2H5PNC8D8P940BJD","01M6KV38CS5B3AY63RKZB410YM",7,"MIT","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002FPDF及文件\u002Fregex-patterns\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000005","邮件与沟通","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"regex","regex patterns","patterns","log","URL","extracting","input","ip","across","practical","debugging","node","python3","text","refactoring","why","data","search","win32","code","2026-11-10 10:12:30",false,"---\nname: regex-patterns\ndescription: Practical regex patterns across languages and use cases. Use when validating input (email, URL, IP), parsing log lines, extracting data from text, refactoring code with search-and-replace, or debugging why a regex doesn't match.\nmetadata: {\"clawdbot\":{\"emoji\":\"?\",\"requires\":{\"anyBins\":[\"grep\",\"python3\",\"node\"]},\"os\":[\"linux\",\"darwin\",\"win32\"]}}\n---\n\n# Regex Patterns\n\nPractical regular expression cookbook. Patterns for validation, parsing, extraction, and refactoring across JavaScript, Python, Go, and command-line tools.\n\n## When to Use\n\n- Validating user input (email, URL, IP, phone, dates)\n- Parsing log lines or structured text\n- Extracting data from strings (IDs, numbers, tokens)\n- Search-and-replace in code (rename variables, update imports)\n- Filtering lines in files or command output\n- Debugging regexes that don't match as expected\n\n## Quick Reference\n\n### Metacharacters\n\n| Pattern | Matches | Example |\n|---|---|---|\n| `.` | Any character (except newline) | `a.c` matches `abc`, `a1c` |\n| `\\d` | Digit `[0-9]` | `\\d{3}` matches `123` |\n| `\\w` | Word char `[a-zA-Z0-9_]` | `\\w+` matches `hello_123` |\n| `\\s` | Whitespace `[ \\t\\n\\r\\f]` | `\\s+` matches spaces\u002Ftabs |\n| `\\b` | Word boundary | `\\bcat\\b` matches `cat` not `scatter` |\n| `^` | Start of line | `^Error` matches line starting with Error |\n| `$` | End of line | `\\.js$` matches line ending with .js |\n| `\\D`, `\\W`, `\\S` | Negated: non-digit, non-word, non-space | |\n\n### Quantifiers\n\n| Pattern | Meaning |\n|---|---|\n| `*` | 0 or more (greedy) |\n| `+` | 1 or more (greedy) |\n| `?` | 0 or 1 (optional) |\n| `{3}` | Exactly 3 |\n| `{2,5}` | Between 2 and 5 |\n| `{3,}` | 3 or more |\n| `*?`, `+?` | Lazy (match as few as possible) |\n\n### Groups and Alternation\n\n| Pattern | Meaning |\n|---|---|\n| `(abc)` | Capture group |\n| `(?:abc)` | Non-capturing group |\n| `(?P\u003Cname>abc)` | Named group (Python) |\n| `(?\u003Cname>abc)` | Named group (JS\u002FGo) |\n| `a\\|b` | Alternation (a or b) |\n| `[abc]` | Character class (a, b, or c) |\n| `[^abc]` | Negated class (not a, b, or c) |\n| `[a-z]` | Range |\n\n### Lookahead and Lookbehind\n\n| Pattern | Meaning |\n|---|---|\n| `(?=abc)` | Positive lookahead (followed by abc) |\n| `(?!abc)` | Negative lookahead (not followed by abc) |\n| `(?\u003C=abc)` | Positive lookbehind (preceded by abc) |\n| `(?\u003C!abc)` | Negative lookbehind (not preceded by abc) |\n\n## Validation Patterns\n\n### Email\n\n```\n# Basic (covers 99% of real emails)\n^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\n\n# Stricter (no consecutive dots, no leading\u002Ftrailing dots in local part)\n^[a-zA-Z0-9]([a-zA-Z0-9._%+-]*[a-zA-Z0-9])?@[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z]{2,})+$\n```\n\n### URL\n\n```\n# HTTP\u002FHTTPS URLs\nhttps?:\u002F\u002F[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*(\u002F[^\\s]*)?\n\n# With optional port and query\nhttps?:\u002F\u002F[^\\s\u002F]+(\u002F[^\\s?]*)?(\\?[^\\s#]*)?(#[^\\s]*)?\n```\n\n### IP Addresses\n\n```\n# IPv4\n\\b(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\b\n\n# IPv4 (simple, allows invalid like 999.999.999.999)\n\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b\n\n# IPv6 (simplified)\n(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\n```\n\n### Phone Numbers\n\n```\n# US phone (various formats)\n(?:\\+1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\n# Matches: +1 (555) 123-4567, 555.123.4567, 5551234567\n\n# International (E.164)\n\\+[1-9]\\d{6,14}\n```\n\n### Dates and Times\n\n```\n# ISO 8601 date\n\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])\n\n# ISO 8601 datetime\n\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})\n\n# US date (MM\u002FDD\u002FYYYY)\n(?:0[1-9]|1[0-2])\u002F(?:0[1-9]|[12]\\d|3[01])\u002F\\d{4}\n\n# Time (HH:MM:SS, 24h)\n(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\n```\n\n### Passwords (Strength Check)\n\n```\n# At least 8 chars, 1 upper, 1 lower, 1 digit, 1 special\n^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_+=-]).{8,}$\n```\n\n### UUIDs\n\n```\n[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\n```\n\n### Semantic Version\n\n```\n\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([\\w.]+))?(?:\\+([\\w.]+))?\\b\n# Captures: major, minor, patch, prerelease, build\n# Matches: 1.2.3, v1.0.0-beta.1, 2.0.0+build.123\n```\n\n## Parsing Patterns\n\n### Log Lines\n\n```bash\n# Apache\u002FNginx access log\n# Format: IP - - [date] \"METHOD \u002Fpath HTTP\u002Fx.x\" status size\ngrep -oP '(\\S+) - - \\[([^\\]]+)\\] \"(\\w+) (\\S+) \\S+\" (\\d+) (\\d+)' access.log\n\n# Extract IP and status code\ngrep -oP '^\\S+|\"\\s\\K\\d{3}' access.log\n\n# Syslog format\n# Format: Mon DD HH:MM:SS hostname process[pid]: message\ngrep -oP '^\\w+\\s+\\d+\\s[\\d:]+\\s(\\S+)\\s(\\S+)\\[(\\d+)\\]:\\s(.*)' syslog\n\n# JSON log — extract a field\ngrep -oP '\"level\"\\s*:\\s*\"\\K[^\"]+' app.log\ngrep -oP '\"message\"\\s*:\\s*\"\\K[^\"]+' app.log\n```\n\n### Code Patterns\n\n```bash\n# Find function definitions (JavaScript\u002FTypeScript)\ngrep -nP '(?:function\\s+\\w+|(?:const|let|var)\\s+\\w+\\s*=\\s*(?:async\\s*)?\\([^)]*\\)\\s*=>|(?:async\\s+)?function\\s*\\()' src\u002F*.ts\n\n# Find class definitions\ngrep -nP 'class\\s+\\w+(?:\\s+extends\\s+\\w+)?' src\u002F*.ts\n\n# Find import statements\ngrep -nP '^import\\s+.*\\s+from\\s+' src\u002F*.ts\n\n# Find TODO\u002FFIXME\u002FHACK comments\ngrep -rnP '(?:TODO|FIXME|HACK|XXX|WARN)(?:\\([^)]+\\))?:?\\s+' src\u002F\n\n# Find console.log left in code\ngrep -rnP 'console\\.(log|debug|info|warn|error)\\(' src\u002F --include='*.ts' --include='*.js'\n```\n\n### Data Extraction\n\n```bash\n# Extract all email addresses from a file\ngrep -oP '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}' file.txt\n\n# Extract all URLs\ngrep -oP 'https?:\u002F\u002F[^\\s\u003C>\"]+' file.html\n\n# Extract all quoted strings\ngrep -oP '\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"' file.json\n\n# Extract numbers (integer and decimal)\ngrep -oP '-?\\d+\\.?\\d*' data.txt\n\n# Extract key-value pairs (key=value)\ngrep -oP '\\b(\\w+)=([^\\s&]+)' query.txt\n\n# Extract hashtags\ngrep -oP '#\\w+' posts.txt\n\n# Extract hex colors\ngrep -oP '#[0-9a-fA-F]{3,8}\\b' styles.css\n```\n\n## Language-Specific Usage\n\n### JavaScript\n\n```javascript\n\u002F\u002F Test if a string matches\nconst emailRegex = \u002F^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\u002F;\nemailRegex.test('user@example.com'); \u002F\u002F true\n\n\u002F\u002F Extract with capture groups\nconst match = '2026-02-03T12:30:00Z'.match(\u002F(\\d{4})-(\\d{2})-(\\d{2})\u002F);\n\u002F\u002F match[1] = '2026', match[2] = '02', match[3] = '03'\n\n\u002F\u002F Named groups\nconst m = 'John Doe, age 30'.match(\u002F(?\u003Cname>[A-Za-z ]+), age (?\u003Cage>\\d+)\u002F);\n\u002F\u002F m.groups.name = 'John Doe', m.groups.age = '30'\n\n\u002F\u002F Find all matches (matchAll returns iterator)\nconst text = 'Call 555-1234 or 555-5678';\nconst matches = [...text.matchAll(\u002F\\d{3}-\\d{4}\u002Fg)];\n\u002F\u002F [{0: '555-1234', index: 5}, {0: '555-5678', index: 18}]\n\n\u002F\u002F Replace with callback\n'hello world'.replace(\u002F\\b\\w\u002Fg, c => c.toUpperCase());\n\u002F\u002F 'Hello World'\n\n\u002F\u002F Replace with named groups\n'2026-02-03'.replace(\u002F(?\u003Cy>\\d{4})-(?\u003Cm>\\d{2})-(?\u003Cd>\\d{2})\u002F, '$\u003Cm>\u002F$\u003Cd>\u002F$\u003Cy>');\n\u002F\u002F '02\u002F03\u002F2026'\n\n\u002F\u002F Split with regex\n'one, two;  three'.split(\u002F[,;]\\s*\u002F);\n\u002F\u002F ['one', 'two', 'three']\n```\n\n### Python\n\n```python\nimport re\n\n# Match (anchored to start)\nm = re.match(r'^(\\w+)@(\\w+)\\.(\\w+)$', 'user@example.com')\nif m:\n    print(m.group(1))  # 'user'\n\n# Search (find first match anywhere)\nm = re.search(r'\\d{3}-\\d{4}', 'Call 555-1234 today')\nprint(m.group())  # '555-1234'\n\n# Find all matches\nemails = re.findall(r'[\\w.+-]+@[\\w.-]+\\.\\w{2,}', text)\n\n# Named groups\nm = re.match(r'(?P\u003Cname>\\w+)\\s+(?P\u003Cage>\\d+)', 'Alice 30')\nprint(m.group('name'))  # 'Alice'\n\n# Substitution\nresult = re.sub(r'\\bfoo\\b', 'bar', 'foo foobar foo')\n# 'bar foobar bar'\n\n# Sub with callback\nresult = re.sub(r'\\b\\w', lambda m: m.group().upper(), 'hello world')\n# 'Hello World'\n\n# Compile for reuse (faster in loops)\npattern = re.compile(r'\\d{4}-\\d{2}-\\d{2}')\ndates = pattern.findall(log_text)\n\n# Multiline and DOTALL\nre.findall(r'^ERROR.*$', text, re.MULTILINE)  # ^ and $ match line boundaries\nre.search(r'start.*end', text, re.DOTALL)      # . matches newlines\n\n# Verbose mode (readable complex patterns)\npattern = re.compile(r'''\n    ^                   # Start of string\n    (?P\u003Cyear>\\d{4})     # Year\n    -(?P\u003Cmonth>\\d{2})   # Month\n    -(?P\u003Cday>\\d{2})     # Day\n    $                   # End of string\n''', re.VERBOSE)\n```\n\n### Go\n\n```go\nimport \"regexp\"\n\n\u002F\u002F Compile pattern (panics on invalid regex)\nre := regexp.MustCompile(`\\d{4}-\\d{2}-\\d{2}`)\n\n\u002F\u002F Match test\nre.MatchString(\"2026-02-03\")  \u002F\u002F true\n\n\u002F\u002F Find first match\nre.FindString(\"Date: 2026-02-03 and 2026-03-01\")  \u002F\u002F \"2026-02-03\"\n\n\u002F\u002F Find all matches\nre.FindAllString(text, -1)  \u002F\u002F []string of all matches\n\n\u002F\u002F Capture groups\nre := regexp.MustCompile(`(\\w+)@(\\w+)\\.(\\w+)`)\nmatch := re.FindStringSubmatch(\"user@example.com\")\n\u002F\u002F match[0] = \"user@example.com\", match[1] = \"user\", match[2] = \"example\"\n\n\u002F\u002F Named groups\nre := regexp.MustCompile(`(?P\u003Cyear>\\d{4})-(?P\u003Cmonth>\\d{2})-(?P\u003Cday>\\d{2})`)\nmatch := re.FindStringSubmatch(\"2026-02-03\")\nfor i, name := range re.SubexpNames() {\n    if name != \"\" {\n        fmt.Printf(\"%s: %s\\n\", name, match[i])\n    }\n}\n\n\u002F\u002F Replace\nre.ReplaceAllString(\"foo123bar\", \"NUM\")  \u002F\u002F \"fooNUMbar\"\n\n\u002F\u002F Replace with function\nre.ReplaceAllStringFunc(text, strings.ToUpper)\n\n\u002F\u002F Note: Go uses RE2 syntax — no lookahead\u002Flookbehind\n```\n\n### Command Line (grep\u002Fsed)\n\n```bash\n# grep -P uses PCRE (Perl-compatible — full features)\n# grep -E uses Extended regex (no lookahead\u002Flookbehind)\n\n# Find lines matching a pattern\ngrep -P '\\d{3}-\\d{4}' file.txt\n\n# Extract only the matching part\ngrep -oP '\\d{3}-\\d{4}' file.txt\n\n# Invert match (lines NOT matching)\ngrep -vP 'DEBUG|TRACE' app.log\n\n# sed replacement\nsed 's\u002FoldPattern\u002FnewText\u002Fg' file.txt         # Basic\nsed -E 's\u002Ffoo_([a-z]+)\u002Fbar_\\1\u002Fg' file.txt     # Extended with capture group\n\n# Perl one-liner (most powerful)\nperl -pe 's\u002F(?\u003C=price:\\s)\\d+\u002F0\u002Fg' file.txt    # Lookbehind works in Perl\n```\n\n## Search-and-Replace Patterns\n\n### Code Refactoring\n\n```bash\n# Rename a variable across files\ngrep -rlP '\\boldName\\b' src\u002F | xargs sed -i 's\u002F\\boldName\\b\u002FnewName\u002Fg'\n\n# Convert var to const (JavaScript)\nsed -i -E 's\u002F\\bvar\\b\u002Fconst\u002Fg' src\u002F*.js\n\n# Convert single quotes to double quotes\nsed -i \"s\u002F'\u002F\\\"\u002Fg\" src\u002F*.ts\n\n# Add trailing commas to object properties\nsed -i -E 's\u002F^(\\s+\\w+:.+[^,])$\u002F\\1,\u002F' config.json\n\n# Update import paths\nsed -i 's|from '\\''..\u002Fold-path\u002F|from '\\''..\u002Fnew-path\u002F|g' src\u002F*.ts\n\n# Convert snake_case to camelCase (Python → JavaScript naming)\nperl -pe 's\u002F_([a-z])\u002Fuc($1)\u002Fge' file.txt\n```\n\n### Text Cleanup\n\n```bash\n# Remove trailing whitespace\nsed -i 's\u002F[[:space:]]*$\u002F\u002F' file.txt\n\n# Remove blank lines\nsed -i '\u002F^$\u002Fd' file.txt\n\n# Remove duplicate blank lines (keep at most one)\nsed -i '\u002F^$\u002FN;\u002F^\\n$\u002Fd' file.txt\n\n# Trim leading and trailing whitespace from each line\nsed -i 's\u002F^[[:space:]]*\u002F\u002F;s\u002F[[:space:]]*$\u002F\u002F' file.txt\n\n# Remove HTML tags\nsed 's\u002F\u003C[^>]*>\u002F\u002Fg' file.html\n\n# Remove ANSI color codes\nsed 's\u002F\\x1b\\[[0-9;]*m\u002F\u002Fg' output.txt\n```\n\n## Common Gotchas\n\n### Greedy vs lazy matching\n\n```\nPattern: \u003C.*>     Input: \u003Cb>bold\u003C\u002Fb>\nGreedy  matches: \u003Cb>bold\u003C\u002Fb>     (entire string between first \u003C and last >)\nLazy    matches: \u003Cb>              (stops at first >)\nPattern: \u003C.*?>    (lazy version)\n```\n\n### Escaping special characters\n\n```\nCharacters that need escaping in regex: . * + ? ^ $ { } [ ] ( ) | \\\nIn character classes []: only ] - ^ \\ need escaping\n\n# To match a literal dot:  \\.\n# To match a literal *:    \\*\n# To match a literal \\:    \\\\\n# To match [ or ]:         \\[ or \\]\n```\n\n### Newlines and multiline\n\n```\nBy default . does NOT match newline.\nBy default ^ and $ match start\u002Fend of STRING.\n\n# To make . match newlines:\nJavaScript: \u002Fpattern\u002Fs (dotAll flag)\nPython: re.DOTALL or re.S\nGo: (?s) inline flag\n\n# To make ^ $ match line boundaries:\nJavaScript: \u002Fpattern\u002Fm (multiline flag)\nPython: re.MULTILINE or re.M\nGo: (?m) inline flag\n```\n\n### Backtracking and performance\n\n```\n# Catastrophic backtracking (avoid these patterns on untrusted input):\n(a+)+        # Nested quantifiers\n(a|a)+       # Overlapping alternation\n(.*a){10}    # Ambiguous .* with repetition\n\n# Safe alternatives:\n[a]+         # Instead of (a+)+\na+           # Instead of (a|a)+\n[^a]*a       # Possessive\u002Fatomic instead of .*a\n```\n\n## Tips\n\n- Start simple and add complexity. `\\d+` is almost always enough — you rarely need `[0-9]+`.\n- Test your regex on real data, not just the happy path. Edge cases (empty strings, special characters, Unicode) break naive patterns.\n- Use non-capturing groups `(?:...)` when you don't need the captured value. It's slightly faster and cleaner.\n- In JavaScript, always use the `g` flag for `matchAll` and global `replace`. Without it, only the first match is found\u002Freplaced.\n- Go's `regexp` package uses RE2 (no lookahead\u002Flookbehind). If you need those, use a different approach or the `regexp2` package.\n- `grep -P` (PCRE) is the most powerful command-line regex. Use it over `grep -E` when you need lookahead, `\\d`, or `\\b`.\n- For complex patterns, use verbose mode (`re.VERBOSE` in Python, `\u002Fx` in Perl) with comments explaining each part.\n- Regex is the wrong tool for parsing HTML, XML, or JSON. Use a proper parser. Regex works for extracting simple values from these formats, not for structural parsing.\n","# Regex Patterns\n\nPractical regular expression cookbook. Patterns for validation, parsing, extraction, and refactoring across JavaScript, Python, Go, and command-line tools.\n\n## When to Use\n\n- Validating user input (email, URL, IP, phone, dates)\n- Parsing log lines or structured text\n- Extracting data from strings (IDs, numbers, tokens)\n- Search-and-replace in code (rename variables, update imports)\n- Filtering lines in files or command output\n- Debugging regexes that don't match as expected\n\n## Quick Reference\n\n### Metacharacters\n\n| Pattern | Matches | Example |\n|---|---|---|\n| `.` | Any character (except newline) | `a.c` matches `abc`, `a1c` |\n| `\\d` | Digit `[0-9]` | `\\d{3}` matches `123` |\n| `\\w` | Word char `[a-zA-Z0-9_]` | `\\w+` matches `hello_123` |\n| `\\s` | Whitespace `[ \\t\\n\\r\\f]` | `\\s+` matches spaces\u002Ftabs |\n| `\\b` | Word boundary | `\\bcat\\b` matches `cat` not `scatter` |\n| `^` | Start of line | `^Error` matches line starting with Error |\n| `$` | End of line | `\\.js$` matches line ending with .js |\n| `\\D`, `\\W`, `\\S` | Negated: non-digit, non-word, non-space | |\n\n### Quantifiers\n\n| Pattern | Meaning |\n|---|---|\n| `*` | 0 or more (greedy) |\n| `+` | 1 or more (greedy) |\n| `?` | 0 or 1 (optional) |\n| `{3}` | Exactly 3 |\n| `{2,5}` | Between 2 and 5 |\n| `{3,}` | 3 or more |\n| `*?`, `+?` | Lazy (match as few as possible) |\n\n### Groups and Alternation\n\n| Pattern | Meaning |\n|---|---|\n| `(abc)` | Capture group |\n| `(?:abc)` | Non-capturing group |\n| `(?P\u003Cname>abc)` | Named group (Python) |\n| `(?\u003Cname>abc)` | Named group (JS\u002FGo) |\n| `a\\|b` | Alternation (a or b) |\n| `[abc]` | Character class (a, b, or c) |\n| `[^abc]` | Negated class (not a, b, or c) |\n| `[a-z]` | Range |\n\n### Lookahead and Lookbehind\n\n| Pattern | Meaning |\n|---|---|\n| `(?=abc)` | Positive lookahead (followed by abc) |\n| `(?!abc)` | Negative lookahead (not followed by abc) |\n| `(?\u003C=abc)` | Positive lookbehind (preceded by abc) |\n| `(?\u003C!abc)` | Negative lookbehind (not preceded by abc) |\n\n## Validation Patterns\n\n### Email\n\n```\n# Basic (covers 99% of real emails)\n^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\n\n# Stricter (no consecutive dots, no leading\u002Ftrailing dots in local part)\n^[a-zA-Z0-9]([a-zA-Z0-9._%+-]*[a-zA-Z0-9])?@[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z]{2,})+$\n```\n\n### URL\n\n```\n# HTTP\u002FHTTPS URLs\nhttps?:\u002F\u002F[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*(\u002F[^\\s]*)?\n\n# With optional port and query\nhttps?:\u002F\u002F[^\\s\u002F]+(\u002F[^\\s?]*)?(\\?[^\\s#]*)?(#[^\\s]*)?\n```\n\n### IP Addresses\n\n```\n# IPv4\n\\b(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\b\n\n# IPv4 (simple, allows invalid like 999.999.999.999)\n\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b\n\n# IPv6 (simplified)\n(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\n```\n\n### Phone Numbers\n\n```\n# US phone (various formats)\n(?:\\+1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\n# Matches: +1 (555) 123-4567, 555.123.4567, 5551234567\n\n# International (E.164)\n\\+[1-9]\\d{6,14}\n```\n\n### Dates and Times\n\n```\n# ISO 8601 date\n\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])\n\n# ISO 8601 datetime\n\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})\n\n# US date (MM\u002FDD\u002FYYYY)\n(?:0[1-9]|1[0-2])\u002F(?:0[1-9]|[12]\\d|3[01])\u002F\\d{4}\n\n# Time (HH:MM:SS, 24h)\n(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\n```\n\n### Passwords (Strength Check)\n\n```\n# At least 8 chars, 1 upper, 1 lower, 1 digit, 1 special\n^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_+=-]).{8,}$\n```\n\n### UUIDs\n\n```\n[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\n```\n\n### Semantic Version\n\n```\n\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([\\w.]+))?(?:\\+([\\w.]+))?\\b\n# Captures: major, minor, patch, prerelease, build\n# Matches: 1.2.3, v1.0.0-beta.1, 2.0.0+build.123\n```\n\n## Parsing Patterns\n\n### Log Lines\n\n```bash\n# Apache\u002FNginx access log\n# Format: IP - - [date] \"METHOD \u002Fpath HTTP\u002Fx.x\" status size\ngrep -oP '(\\S+) - - \\[([^\\]]+)\\] \"(\\w+) (\\S+) \\S+\" (\\d+) (\\d+)' access.log\n\n# Extract IP and status code\ngrep -oP '^\\S+|\"\\s\\K\\d{3}' access.log\n\n# Syslog format\n# Format: Mon DD HH:MM:SS hostname process[pid]: message\ngrep -oP '^\\w+\\s+\\d+\\s[\\d:]+\\s(\\S+)\\s(\\S+)\\[(\\d+)\\]:\\s(.*)' syslog\n\n# JSON log — extract a field\ngrep -oP '\"level\"\\s*:\\s*\"\\K[^\"]+' app.log\ngrep -oP '\"message\"\\s*:\\s*\"\\K[^\"]+' app.log\n```\n\n### Code Patterns\n\n```bash\n# Find function definitions (JavaScript\u002FTypeScript)\ngrep -nP '(?:function\\s+\\w+|(?:const|let|var)\\s+\\w+\\s*=\\s*(?:async\\s*)?\\([^)]*\\)\\s*=>|(?:async\\s+)?function\\s*\\()' src\u002F*.ts\n\n# Find class definitions\ngrep -nP 'class\\s+\\w+(?:\\s+extends\\s+\\w+)?' src\u002F*.ts\n\n# Find import statements\ngrep -nP '^import\\s+.*\\s+from\\s+' src\u002F*.ts\n\n# Find TODO\u002FFIXME\u002FHACK comments\ngrep -rnP '(?:TODO|FIXME|HACK|XXX|WARN)(?:\\([^)]+\\))?:?\\s+' src\u002F\n\n# Find console.log left in code\ngrep -rnP 'console\\.(log|debug|info|warn|error)\\(' src\u002F --include='*.ts' --include='*.js'\n```\n\n### Data Extraction\n\n```bash\n# Extract all email addresses from a file\ngrep -oP '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}' file.txt\n\n# Extract all URLs\ngrep -oP 'https?:\u002F\u002F[^\\s\u003C>\"]+' file.html\n\n# Extract all quoted strings\ngrep -oP '\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"' file.json\n\n# Extract numbers (integer and decimal)\ngrep -oP '-?\\d+\\.?\\d*' data.txt\n\n# Extract key-value pairs (key=value)\ngrep -oP '\\b(\\w+)=([^\\s&]+)' query.txt\n\n# Extract hashtags\ngrep -oP '#\\w+' posts.txt\n\n# Extract hex colors\ngrep -oP '#[0-9a-fA-F]{3,8}\\b' styles.css\n```\n\n## Language-Specific Usage\n\n### JavaScript\n\n```javascript\n\u002F\u002F Test if a string matches\nconst emailRegex = \u002F^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\u002F;\nemailRegex.test('user@example.com'); \u002F\u002F true\n\n\u002F\u002F Extract with capture groups\nconst match = '2026-02-03T12:30:00Z'.match(\u002F(\\d{4})-(\\d{2})-(\\d{2})\u002F);\n\u002F\u002F match[1] = '2026', match[2] = '02', match[3] = '03'\n\n\u002F\u002F Named groups\nconst m = 'John Doe, age 30'.match(\u002F(?\u003Cname>[A-Za-z ]+), age (?\u003Cage>\\d+)\u002F);\n\u002F\u002F m.groups.name = 'John Doe', m.groups.age = '30'\n\n\u002F\u002F Find all matches (matchAll returns iterator)\nconst text = 'Call 555-1234 or 555-5678';\nconst matches = [...text.matchAll(\u002F\\d{3}-\\d{4}\u002Fg)];\n\u002F\u002F [{0: '555-1234', index: 5}, {0: '555-5678', index: 18}]\n\n\u002F\u002F Replace with callback\n'hello world'.replace(\u002F\\b\\w\u002Fg, c => c.toUpperCase());\n\u002F\u002F 'Hello World'\n\n\u002F\u002F Replace with named groups\n'2026-02-03'.replace(\u002F(?\u003Cy>\\d{4})-(?\u003Cm>\\d{2})-(?\u003Cd>\\d{2})\u002F, '$\u003Cm>\u002F$\u003Cd>\u002F$\u003Cy>');\n\u002F\u002F '02\u002F03\u002F2026'\n\n\u002F\u002F Split with regex\n'one, two;  three'.split(\u002F[,;]\\s*\u002F);\n\u002F\u002F ['one', 'two', 'three']\n```\n\n### Python\n\n```python\nimport re\n\n# Match (anchored to start)\nm = re.match(r'^(\\w+)@(\\w+)\\.(\\w+)$', 'user@example.com')\nif m:\n    print(m.group(1))  # 'user'\n\n# Search (find first match anywhere)\nm = re.search(r'\\d{3}-\\d{4}', 'Call 555-1234 today')\nprint(m.group())  # '555-1234'\n\n# Find all matches\nemails = re.findall(r'[\\w.+-]+@[\\w.-]+\\.\\w{2,}', text)\n\n# Named groups\nm = re.match(r'(?P\u003Cname>\\w+)\\s+(?P\u003Cage>\\d+)', 'Alice 30')\nprint(m.group('name'))  # 'Alice'\n\n# Substitution\nresult = re.sub(r'\\bfoo\\b', 'bar', 'foo foobar foo')\n# 'bar foobar bar'\n\n# Sub with callback\nresult = re.sub(r'\\b\\w', lambda m: m.group().upper(), 'hello world')\n# 'Hello World'\n\n# Compile for reuse (faster in loops)\npattern = re.compile(r'\\d{4}-\\d{2}-\\d{2}')\ndates = pattern.findall(log_text)\n\n# Multiline and DOTALL\nre.findall(r'^ERROR.*$', text, re.MULTILINE)  # ^ and $ match line boundaries\nre.search(r'start.*end', text, re.DOTALL)      # . matches newlines\n\n# Verbose mode (readable complex patterns)\npattern = re.compile(r'''\n    ^                   # Start of string\n    (?P\u003Cyear>\\d{4})     # Year\n    -(?P\u003Cmonth>\\d{2})   # Month\n    -(?P\u003Cday>\\d{2})     # Day\n    $                   # End of string\n''', re.VERBOSE)\n```\n\n### Go\n\n```go\nimport \"regexp\"\n\n\u002F\u002F Compile pattern (panics on invalid regex)\nre := regexp.MustCompile(`\\d{4}-\\d{2}-\\d{2}`)\n\n\u002F\u002F Match test\nre.MatchString(\"2026-02-03\")  \u002F\u002F true\n\n\u002F\u002F Find first match\nre.FindString(\"Date: 2026-02-03 and 2026-03-01\")  \u002F\u002F \"2026-02-03\"\n\n\u002F\u002F Find all matches\nre.FindAllString(text, -1)  \u002F\u002F []string of all matches\n\n\u002F\u002F Capture groups\nre := regexp.MustCompile(`(\\w+)@(\\w+)\\.(\\w+)`)\nmatch := re.FindStringSubmatch(\"user@example.com\")\n\u002F\u002F match[0] = \"user@example.com\", match[1] = \"user\", match[2] = \"example\"\n\n\u002F\u002F Named groups\nre := regexp.MustCompile(`(?P\u003Cyear>\\d{4})-(?P\u003Cmonth>\\d{2})-(?P\u003Cday>\\d{2})`)\nmatch := re.FindStringSubmatch(\"2026-02-03\")\nfor i, name := range re.SubexpNames() {\n    if name != \"\" {\n        fmt.Printf(\"%s: %s\\n\", name, match[i])\n    }\n}\n\n\u002F\u002F Replace\nre.ReplaceAllString(\"foo123bar\", \"NUM\")  \u002F\u002F \"fooNUMbar\"\n\n\u002F\u002F Replace with function\nre.ReplaceAllStringFunc(text, strings.ToUpper)\n\n\u002F\u002F Note: Go uses RE2 syntax — no lookahead\u002Flookbehind\n```\n\n### Command Line (grep\u002Fsed)\n\n```bash\n# grep -P uses PCRE (Perl-compatible — full features)\n# grep -E uses Extended regex (no lookahead\u002Flookbehind)\n\n# Find lines matching a pattern\ngrep -P '\\d{3}-\\d{4}' file.txt\n\n# Extract only the matching part\ngrep -oP '\\d{3}-\\d{4}' file.txt\n\n# Invert match (lines NOT matching)\ngrep -vP 'DEBUG|TRACE' app.log\n\n# sed replacement\nsed 's\u002FoldPattern\u002FnewText\u002Fg' file.txt         # Basic\nsed -E 's\u002Ffoo_([a-z]+)\u002Fbar_\\1\u002Fg' file.txt     # Extended with capture group\n\n# Perl one-liner (most powerful)\nperl -pe 's\u002F(?\u003C=price:\\s)\\d+\u002F0\u002Fg' file.txt    # Lookbehind works in Perl\n```\n\n## Search-and-Replace Patterns\n\n### Code Refactoring\n\n```bash\n# Rename a variable across files\ngrep -rlP '\\boldName\\b' src\u002F | xargs sed -i 's\u002F\\boldName\\b\u002FnewName\u002Fg'\n\n# Convert var to const (JavaScript)\nsed -i -E 's\u002F\\bvar\\b\u002Fconst\u002Fg' src\u002F*.js\n\n# Convert single quotes to double quotes\nsed -i \"s\u002F'\u002F\\\"\u002Fg\" src\u002F*.ts\n\n# Add trailing commas to object properties\nsed -i -E 's\u002F^(\\s+\\w+:.+[^,])$\u002F\\1,\u002F' config.json\n\n# Update import paths\nsed -i 's|from '\\''..\u002Fold-path\u002F|from '\\''..\u002Fnew-path\u002F|g' src\u002F*.ts\n\n# Convert snake_case to camelCase (Python → JavaScript naming)\nperl -pe 's\u002F_([a-z])\u002Fuc($1)\u002Fge' file.txt\n```\n\n### Text Cleanup\n\n```bash\n# Remove trailing whitespace\nsed -i 's\u002F[[:space:]]*$\u002F\u002F' file.txt\n\n# Remove blank lines\nsed -i '\u002F^$\u002Fd' file.txt\n\n# Remove duplicate blank lines (keep at most one)\nsed -i '\u002F^$\u002FN;\u002F^\\n$\u002Fd' file.txt\n\n# Trim leading and trailing whitespace from each line\nsed -i 's\u002F^[[:space:]]*\u002F\u002F;s\u002F[[:space:]]*$\u002F\u002F' file.txt\n\n# Remove HTML tags\nsed 's\u002F\u003C[^>]*>\u002F\u002Fg' file.html\n\n# Remove ANSI color codes\nsed 's\u002F\\x1b\\[[0-9;]*m\u002F\u002Fg' output.txt\n```\n\n## Common Gotchas\n\n### Greedy vs lazy matching\n\n```\nPattern: \u003C.*>     Input: \u003Cb>bold\u003C\u002Fb>\nGreedy  matches: \u003Cb>bold\u003C\u002Fb>     (entire string between first \u003C and last >)\nLazy    matches: \u003Cb>              (stops at first >)\nPattern: \u003C.*?>    (lazy version)\n```\n\n### Escaping special characters\n\n```\nCharacters that need escaping in regex: . * + ? ^ $ { } [ ] ( ) | \\\nIn character classes []: only ] - ^ \\ need escaping\n\n# To match a literal dot:  \\.\n# To match a literal *:    \\*\n# To match a literal \\:    \\\\\n# To match [ or ]:         \\[ or \\]\n```\n\n### Newlines and multiline\n\n```\nBy default . does NOT match newline.\nBy default ^ and $ match start\u002Fend of STRING.\n\n# To make . match newlines:\nJavaScript: \u002Fpattern\u002Fs (dotAll flag)\nPython: re.DOTALL or re.S\nGo: (?s) inline flag\n\n# To make ^ $ match line boundaries:\nJavaScript: \u002Fpattern\u002Fm (multiline flag)\nPython: re.MULTILINE or re.M\nGo: (?m) inline flag\n```\n\n### Backtracking and performance\n\n```\n# Catastrophic backtracking (avoid these patterns on untrusted input):\n(a+)+        # Nested quantifiers\n(a|a)+       # Overlapping alternation\n(.*a){10}    # Ambiguous .* with repetition\n\n# Safe alternatives:\n[a]+         # Instead of (a+)+\na+           # Instead of (a|a)+\n[^a]*a       # Possessive\u002Fatomic instead of .*a\n```\n\n## Tips\n\n- Start simple and add complexity. `\\d+` is almost always enough — you rarely need `[0-9]+`.\n- Test your regex on real data, not just the happy path. Edge cases (empty strings, special characters, Unicode) break naive patterns.\n- Use non-capturing groups `(?:...)` when you don't need the captured value. It's slightly faster and cleaner.\n- In JavaScript, always use the `g` flag for `matchAll` and global `replace`. Without it, only the first match is found\u002Freplaced.\n- Go's `regexp` package uses RE2 (no lookahead\u002Flookbehind). If you need those, use a different approach or the `regexp2` package.\n- `grep -P` (PCRE) is the most powerful command-line regex. Use it over `grep -E` when you need lookahead, `\\d`, or `\\b`.\n- For complex patterns, use verbose mode (`re.VERBOSE` in Python, `\u002Fx` in Perl) with comments explaining each part.\n- Regex is the wrong tool for parsing HTML, XML, or JSON. Use a proper parser. Regex works for extracting simple values from these formats, not for structural parsing.\n",{"name":5,"metadata":48,"description":7},{"clawdbot":49},{"os":50,"emoji":53,"requires":54},[51,52,41],"linux","darwin","?",{"anyBins":55},[56,35,34],"grep","main","f4cb2d49f7667e79ef7804f50396d5aaffdf1f56","PDF及文件\u002Fregex-patterns",1,"https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification","https:\u002F\u002Fgithub.com\u002FKernel8901","a little little little dobe in life but science geek","2026-04-05 16:43:56",{"source":8,"skillName":5,"commands":66,"prompt":76,"zipAvailable":77},[67,70,73],{"tool":68,"command":69},"npx","npx skills add Kernel8901\u002Fai-agent-skills-classification --skill regex-patterns",{"tool":71,"command":72},"bunx","bunx skills add Kernel8901\u002Fai-agent-skills-classification --skill regex-patterns",{"tool":74,"command":75},"pnpm","pnpm dlx skills add Kernel8901\u002Fai-agent-skills-classification --skill regex-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002FPDF及文件\u002Fregex-patterns\u002FSKILL.md",true,[79],{"path":80,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":83,"sourceHtmlUrl":84},"_meta.json","REFERENCE","参考文档",292,"https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002FPDF及文件\u002Fregex-patterns\u002F_meta.json",[86,110,143,154,164,193],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":43},"01M6Q5R6WZ06RRB9RQTW54B34B","zyfai","Earn yield on any Ethereum wallet on Base, Arbitrum, and Plasma. Use when a user wants passive DeFi yield on their funds. Deploys a non-custodial subaccount (Safe) linked to their EOA, enables automated yield optimization, and lets them deposit\u002Fwithdraw anytime.","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002F金融\u002Fzyfai-sdk\u002FSKILL.md",[],[88,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109],"safe","ethereum","defi","Optimization","user","use","Wallet","base","deposit","withdraw","yield","arbitrum","non-custodial","passive","defi yield","earn","yield optimization",{"skillNo":111,"name":112,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":126,"publishedAt":43},"01M6Q5R337B5JSNER4P4YS03TN","zerion-api","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002F金融\u002Fzerion-api\u002FSKILL.md",[115,118,121],{"categoryNo":116,"categoryName":117,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":119,"categoryName":120,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[127,128,129,130,131,132,133,95,134,99,135,136,137,138,139,31,140,141,142],"api","zerion api","zerion","MCP","mcp server","server","blockchain","transactions","crypto wallet","crypto","evm","solana","query","positions","token","prices",{"skillNo":144,"name":145,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":151,"publishedAt":43},"01M6Q5QZFYTDAZMZ27BN5VZXAR","zerion-api-skill","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002F金融\u002Fzerion-api-skill\u002FSKILL.md",[148,149,150],{"categoryNo":116,"categoryName":117,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":119,"categoryName":120,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},[127,152,153,128,129,130,131,132,133,95,134,99,136,137,138,139,31,140,141,142],"api skill","zerion api skill",{"skillNo":155,"name":156,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":162,"publishedAt":43},"01M6Q5QW17QW98RA3FE45E4RD8","zerion-api-mcp","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002F金融\u002Fzerion-api-mcp\u002FSKILL.md",[159,160,161],{"categoryNo":116,"categoryName":117,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":119,"categoryName":120,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},[130,127,163,128,129,131,132,95,134,99,135,136,137,138,139,31,140,141,142],"zerion api mcp",{"skillNo":165,"name":166,"nameZh":6,"description":167,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":168,"categories":169,"keywords":173,"publishedAt":43},"01M6Q5QQYZB7A501BDEQWKGSJT","yahoo-finance-forex","Fetches real-time FOREX news and market data from Yahoo Finance for major currency pairs (EUR\u002FUSD, GBP\u002FUSD, USD\u002FJPY, etc.). Analyzes sentiment and provides trading context.","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002F金融\u002Fyahoo-finance-forex\u002FSKILL.md",[170],{"categoryNo":171,"categoryName":172,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000040","财务",[174,175,176,177,178,179,180,181,182,35,183,184,185,186,187,188,189,190,191,192],"finance","yahoo finance","forex","yahoo","yahoo finance forex","github","https","sentiment","real-time","install","Market","usd","news","time","currency","gbp","pip","market data","for",{"skillNo":194,"name":195,"nameZh":6,"description":196,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":197,"categories":198,"keywords":200,"publishedAt":43},"01M6Q5QM6VS84WZVM7BKXXPF32","yahoo-finance","This skill should be used when the user asks to \"get stock prices\", \"check stock quotes\", \"look up earnings\", \"get financial data\", \"find trending stocks\", or needs stock market data from Yahoo Finance.","https:\u002F\u002Fgithub.com\u002FKernel8901\u002Fai-agent-skills-classification\u002Fblob\u002Fmain\u002F金融\u002Fyahoo-finance-cli\u002FSKILL.md",[199],{"categoryNo":171,"categoryName":172,"taxonomyType":124,"taxonomyTypeDesc":125},[174,175,177,201,202,203,204,205,206,184,207,208,209,210,211,212,213,214,142,191],"cli","homebrew","find","check","brew","up","local","get","stock","link","trending","sf","quotes","ln"]