├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── .idocrc.mjs ├── LICENSE ├── README.md ├── package.json ├── regulex └── index.html ├── renovate.json └── scripts └── style.css /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: jaywcjlove 2 | buy_me_a_coffee: jaywcjlove 3 | custom: ["https://www.paypal.me/kennyiseeyou", "https://jaywcjlove.github.io/#/sponsor"] 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | Build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: actions/setup-node@v4 13 | with: 14 | node-version: 20 15 | 16 | - run: npm install 17 | - run: npm run doc 18 | 19 | - name: Generate Contributors Images 20 | uses: jaywcjlove/github-action-contributors@main 21 | with: 22 | filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\]) 23 | output: dist/CONTRIBUTORS.svg 24 | avatarSize: 42 25 | 26 | - name: Create Tag 27 | id: create_tag 28 | uses: jaywcjlove/create-tag-action@main 29 | with: 30 | package-path: package.json 31 | 32 | - name: get tag version 33 | id: tag_version 34 | uses: jaywcjlove/changelog-generator@main 35 | 36 | - name: Deploy 37 | uses: peaceiris/actions-gh-pages@v4 38 | with: 39 | commit_message: ${{steps.tag_version.outputs.tag}} ${{ github.event.head_commit.message }} 40 | github_token: ${{ secrets.GITHUB_TOKEN }} 41 | publish_dir: ./dist 42 | 43 | - name: Generate Changelog 44 | id: changelog 45 | uses: jaywcjlove/changelog-generator@main 46 | with: 47 | head-ref: ${{steps.create_tag.outputs.version}} 48 | filter-author: (小弟调调™|Renovate Bot) 49 | filter: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}' 50 | 51 | - name: Create Release 52 | uses: ncipollo/release-action@v1 53 | if: steps.create_tag.outputs.successful 54 | with: 55 | allowUpdates: true 56 | name: ${{ steps.create_tag.outputs.version }} 57 | tag: ${{ steps.create_tag.outputs.version }} 58 | token: ${{ secrets.GITHUB_TOKEN }} 59 | body: | 60 | [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor) 61 | 62 | Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/regexp-example/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html 63 | Comparing Changes: ${{ steps.changelog.outputs.compareurl }} 64 | 65 | ${{ steps.changelog.outputs.changelog }} 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | web 2 | dist 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | 12 | # Diagnostic reports (https://nodejs.org/api/report.html) 13 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 14 | 15 | # Runtime data 16 | pids 17 | *.pid 18 | *.seed 19 | *.pid.lock 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | 27 | node_modules 28 | package-lock.json 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | .DS_Store 33 | .cache 34 | .vscode 35 | .idea 36 | .snap 37 | .env 38 | 39 | *.lcov 40 | *.bak 41 | *.tem 42 | *.temp 43 | #.swp 44 | *.*~ 45 | ~*.* 46 | 47 | # IDEA 48 | *.iml 49 | *.ipr 50 | *.iws -------------------------------------------------------------------------------- /.idocrc.mjs: -------------------------------------------------------------------------------- 1 | import FS from 'fs-extra'; 2 | import path from 'path'; 3 | 4 | const style = FS.readFileSync(path.resolve(process.cwd(), 'scripts/style.css')).toString(); 5 | const script = ` 6 | const inputs = document.querySelector('markdown-style').querySelectorAll('input'); 7 | Array.from(inputs).forEach((elm) => { 8 | const code = (elm.dataset.code || '').replace(/\\n/g, ''); 9 | elm.oninput = (evn) => { 10 | const isChecked = new RegExp(code).test(evn.target.value); 11 | elm.className = isChecked ? 'success' : 'danger'; 12 | if (elm.nextSibling) { 13 | elm.nextSibling.innerHTML = isChecked ? '通过' : '×不通过' 14 | elm.nextSibling.className = isChecked ? 'success' : 'danger'; 15 | } 16 | } 17 | });`; 18 | 19 | const getCodeStr = (data = [], code = '') => { 20 | data.forEach((node) => { 21 | if (node.type === 'text') { 22 | code += node.value; 23 | } else if (node.type === 'element' && node.children && Array.isArray(node.children)) { 24 | code += getCodeStr(node.children); 25 | } 26 | }); 27 | return code; 28 | }; 29 | 30 | const input = (code) => { 31 | return { 32 | type: 'element', 33 | tagName: 'div', 34 | properties: { className: 'regex', }, 35 | children: [ 36 | { 37 | type: 'element', 38 | tagName: 'input', 39 | properties: { 40 | type: 'text', value: '', placeholder: '请输入下方【E.g】字符串验证实例', 'data-code': code || '', 41 | }, 42 | }, 43 | { 44 | type: 'element', 45 | tagName: 'span', 46 | properties: { className: 'info' }, 47 | } 48 | ] 49 | } 50 | } 51 | 52 | const toolbar = (copied) => { 53 | return { 54 | type: 'element', 55 | tagName: 'div', 56 | properties: { className: 'issue' }, 57 | children: [ 58 | { 59 | type: 'element', 60 | tagName: 'a', 61 | properties: { 62 | target: '__blank', 63 | className: 'share', 64 | href: `https://jaywcjlove.github.io/regexp-example/regulex/index.html#!flags=&re=${encodeURIComponent(copied)}` 65 | }, 66 | children: [ 67 | { type: 'text', value: '分享例子' } 68 | ] 69 | }, 70 | { 71 | type: 'element', 72 | tagName: 'a', 73 | properties: { 74 | target: '__blank', 75 | href: `https://github.com/jaywcjlove/regexp-example/issues/new?labels=bug,enhancement&assignees=jaywcjlove&body=❌ 正则:~~\`${copied}\`~~%0a✅ 正则:\`正则示例\`&title=修改实例:xxx` 76 | }, 77 | children: [ 78 | { type: 'text', value: '🐞修改正则' } 79 | ] 80 | } 81 | ], 82 | } 83 | } 84 | 85 | const createLink = () => ([ 86 | { 87 | type: 'element', 88 | tagName: 'a', 89 | properties: { 90 | className: 'btn create', 91 | target: '__blank', 92 | href: `https://github.com/jaywcjlove/regexp-example/issues/new?labels=new,enhancement&assignees=jaywcjlove&body=&title=新增实例:xxx` 93 | }, 94 | children: [ 95 | { type: 'text', value: '分享例子' } 96 | ] 97 | }, 98 | ]); 99 | 100 | const stylestr =` 101 | .language-regex span.range { border: 1px dotted; border-color: transparent; color: var(--color-prettylights-syntax-meta-diff-range); } 102 | .language-regex span.range:hover { border: 1px dotted var(--color-prettylights-syntax-brackethighlighter-unmatched); } 103 | .language-regex span.char-class { color: var(--color-prettylights-syntax-markup-inserted-text); } 104 | .language-regex .token.punctuation { color: var(--color-prettylights-syntax-markup-changed-text); } 105 | .language-regex .token.group { color: var(--color-prettylights-syntax-carriage-return-bg); } 106 | .language-regex .token.char-set, 107 | .language-regex .token.number, 108 | .language-regex .token.range, 109 | .language-regex .token.anchor { font-weight: bold; } 110 | .language-regex .token.anchor { color: var(--color-prettylights-syntax-markup-inserted-text); } 111 | 112 | span.charset { background: #fff9c0; } 113 | div.regex { display: flex; align-items: center; position: relative; padding: 0 10px 10px 10px;} 114 | div.regex input { 115 | transition: all .5s; 116 | outline: none; 117 | border: none; 118 | padding: 4px 6px; 119 | padding-right: 60px; 120 | border-radius: 3px; 121 | box-sizing: border-box; 122 | line-height: 18px; 123 | flex: 1; 124 | } 125 | div.regex input::placeholder { 126 | color: var(--color-fg-muted); 127 | } 128 | div.regex input.success { box-shadow: 0 0 0 1px #ffffff, 0 0 0 3px #15ae3c, inset 0 1px 1px rgb(16 22 26 / 0%) !important; } 129 | div.regex input.danger { box-shadow: 0 0 0 1px #ffffff, 0 0 0 3px #e91e63, inset 0 1px 1px rgb(16 22 26 / 0%) !important; } 130 | div.regex input:hover { box-shadow: 0 0 0 1px #ffffff, 0 0 0 3px rgb(55 109 217 / 21%), inset 0 1px 1px rgb(16 22 26 / 0%); } 131 | div.regex span.success, 132 | div.regex span.danger { position: absolute; right: 3px; line-height: 16px; padding: 2px 5px; border-radius: 4px; margin-right: 10px; } 133 | div.regex span.success { 134 | color: #00ad36; 135 | background-color: #cef3cf; 136 | } 137 | div.regex span.danger { 138 | color: #cb0649; 139 | background-color: #fbdcdc; 140 | margin-left: 10px; 141 | } 142 | markdown-style pre[class*="language-regex"] span.anchor { 143 | float: initial; 144 | padding-right: initial; 145 | margin-left: initial; 146 | } 147 | markdown-style pre[class*="language-regex"] { 148 | overflow: initial; 149 | transition: background-color .5s; 150 | border-radius: 6px; 151 | } 152 | markdown-style pre[class*="language-regex"] code { 153 | background-color: transparent; 154 | } 155 | markdown-style pre[class*="language-regex"]:hover { 156 | background-color: var(--color-border-muted); 157 | } 158 | markdown-style pre[class*="language-regex"]:hover .issue { 159 | visibility: visible; 160 | } 161 | markdown-style pre[class*="language-regex"]:hover .issue a { 162 | transition: opacity .5s; 163 | opacity: 1; 164 | } 165 | markdown-style pre[class*="language-regex"] .issue { 166 | position: absolute; 167 | right: 3px; 168 | margin-top: -16px; 169 | padding: 0 0 5px 0; 170 | font-size: 12px; 171 | } 172 | markdown-style pre[class*="language-regex"] .issue a { 173 | background: #ff5722; 174 | padding: 3px 5px; 175 | border-radius: 2px; 176 | color: #fff; 177 | opacity: 0.15; 178 | } 179 | markdown-style pre[class*="language-regex"] .issue a + a { 180 | margin-left: 5px; 181 | } 182 | markdown-style pre[class*="language-regex"] .issue a.share { 183 | background: #009688; 184 | } 185 | markdown-style pre[class*="language-regex"] .issue a.copied { 186 | background: #4caf50; 187 | } 188 | markdown-style pre > code[class*="language-regex"] { 189 | word-break: break-all !important; 190 | white-space: initial !important; 191 | } 192 | markdown-style h2 { 193 | border-bottom: 0 !important; 194 | } 195 | ${style} 196 | `; 197 | 198 | const styleElement = { 199 | type: 'element', 200 | properties: {}, 201 | tagName: 'style', 202 | children: [ 203 | { type: 'text', value: stylestr, } 204 | ] 205 | } 206 | 207 | /** @type {Array} */ 208 | const meta = [ 209 | '', 210 | '', 211 | '', 212 | // '', 213 | '', 214 | '', 215 | '', 216 | ] 217 | /** 218 | * @typedef {import("idoc").Config} Config 219 | * @type {Config} 220 | */ 221 | export default { 222 | output: "dist", 223 | site: "RegExp Example 正则实例", 224 | menus: { 225 | "赞助": { 226 | url: "https://jaywcjlove.github.io/#/sponsor", 227 | target: "__blank" 228 | } 229 | }, 230 | meta, 231 | rewrite: (node) => { 232 | if ((node.type === 'comment' && node.value === 'regulex') || (node.type === 'raw' && node.value === '')) { 233 | node.type = 'element'; 234 | node.tagName = 'iframe'; 235 | node.properties = { 236 | style: 'border: 0; width: 100%; min-height: 370px; margin-bottom: 16px; border-radius: 6px; background: #edf2f5;', 237 | src: 'regulex/index.html', 238 | visible: 0, 239 | } 240 | } 241 | if (node.type === "root") { 242 | node.children = [ ...createLink(), ...node.children]; 243 | node.children.push(styleElement) 244 | node.children.push({ 245 | type: 'element', tagName: 'script', 246 | properties: {}, 247 | children: [{ 248 | type: 'text', 249 | value: script 250 | }] 251 | }); 252 | } 253 | if (node.tagName === 'pre' && node.properties.className) { 254 | const lang = Array.isArray(node.properties.className) ? node.properties.className.join('') : node.properties.className; 255 | if (/-regex$/.test(lang)) { 256 | const regStr = getCodeStr(node.children); 257 | node.children = [ toolbar(regStr), ...node.children, input(regStr) ]; 258 | } 259 | } 260 | } 261 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 小弟调调™ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RegExp Example 2 | === 3 | 4 | 5 | [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor) 6 | [![CI](https://github.com/jaywcjlove/regexp-example/actions/workflows/ci.yml/badge.svg)](https://github.com/jaywcjlove/regexp-example/actions/workflows/ci.yml) 7 | 8 | 正则表达式实例搜集,通过实例来学习正则表达式。本仓库实例搜集整理来自于[**《一些正则表达式随记》**](https://github.com/jaywcjlove/handbook/blob/master/docs/JavaScript/RegExp.md),通过一个单独仓库专门整理这些正则实例,提供一个[**实例网站**](https://jaywcjlove.github.io/regexp-example),方便正则实例验证和查询。也方便[**添加**](https://github.com/jaywcjlove/regexp-example/issues/new?labels=new&assignees=jaywcjlove&title=%E6%B7%BB%E5%8A%A0%E6%96%B0%E5%AE%9E%E4%BE%8B%EF%BC%9A) 新的正则实例大家共同维护。 9 | 10 | RegexMate for macOS/iOS 11 | 12 | 13 | [表达式全集](#表达式全集) · [Example](#example) · [工具推荐](#工具推荐) · [国内镜像站点🇨🇳](https://jaywcjlove.gitee.io/regexp-example) · [Gitee](https://gitee.com/jaywcjlove/regexp-example) · [License](#license) 14 | 15 | 16 | 17 | 如果有一些基础知识,通过实例理解,将会更快速入门,写出自己的正则。如果对基础还不是很了解,你可以通过[**《Learn regex the easy way》**](https://github.com/ziishaned/learn-regex)去学习基础知识,这个仓库教程被翻译成十几种语言了,包含了[中文翻译](https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md),它通过极其简单的实例,帮助你理解正则基础语法规则。 18 | 19 | ## 表达式全集 20 | 21 |
22 | 元字符 23 | 24 | 正则表达式主要依赖于元字符。 25 | 元字符不代表他们本身的字面意思,他们都有特殊的含义。一些元字符写在方括号中的时候有一些特殊的意思。以下是一些元字符的介绍: 26 | 27 | 字符 | 描述 28 | ---- | ---- 29 | . | 句号匹配任意单个字符除了换行符。要匹配包括 `\n` 在内的任何字符,请使用像 `(.\|\n)` 的模式。 30 | [ ] | 字符种类。匹配方括号内的任意字符。 31 | [^ ] | 否定的字符种类。匹配除了方括号里的任意字符 32 | \* | 匹配 >=0 个重复的在 `*` 号之前的字符。例如,`zo*` 能匹配 `z` 以及 `zoo` 。`*` 等价于 `{0,}`。 33 | \+ | 匹配 >=1 个重复的 `+` 号前的字符。例如, `zo+` 能匹配 `zo` 以及 `zoo` ,但不能匹配 `z` 。`+` 等价于 `{1,}`。 34 | ? | 标记 ? 之前的字符为可选。例如,`do(es)?` 可以匹配 `does` 或 `does` 中的 `do`。`?` 等价于 `{0,1}`。 35 | | | 或运算符,匹配符号前或后的字符。例如,`z|food` 能匹配 `z` 或 `food`。`(z|f)ood` 则匹配 `zood` 或 `food`。 36 | \ | 转义字符,用于匹配一些保留的字符 `[ ] ( ) { } . * + ? ^ $ \ |` 37 | ^ | 从开始行开始匹配。 38 | $ | 从末端开始匹配。 39 | {n} | `n` 是一个非负整数。匹配确定的n次。例如, `o{2}` 不能匹配 `Bob` 中的 `o` ,但是能匹配 `food` 中的两个 `o`。 40 | {n,} | `n` 是一个非负整数。至少匹配n次。例如, `o{2,}`不能匹配 `Bob`中的 `o`,但能匹配 `foooood`中的所有o。 `o{1,}`等价于 `o+`。 `o{0,}`则等价于 `o*`。 41 | {n,m} | `m` 和 `n` 均为非负整数,其中 `n<=m`。最少匹配 `n` 次且最多匹配 `m` 次。例如,`o{1,3}` 将匹配 `fooooood` 中的前三个 `o`。`o{0,1}` 等价于 `o?`。请注意在逗号和两个数之间不能有空格。 42 | (xyz) | 字符集,匹配与 `xyz` 完全相等的字符串. 43 | [xyz] | 字符集合。匹配所包含的任意一个字符。例如,`[abc]` 可以匹配 `plain` 中的 `a`。 44 | [^xyz] | 负值字符集合。匹配未包含的任意字符。例如, `[^abc]` 可以匹配 `plain` 中的 `p`。 45 | [a-z] | 字符范围。匹配指定范围内的任意字符。例如,`[a-z]` 可以匹配 `a` 到 `z` 范围内的任意小写字母字符。 46 | [^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,`[^a-z]` 可以匹配任何不在 `a` 到 `z` 范围内的任意字符。 47 | 48 |
49 | 50 |
51 | 字符集简写 52 | 53 | 正则表达式提供一些常用的字符集简写。如下: 54 | 55 | 简写 | 描述 56 | ---- | ---- 57 | . | 除换行符外的所有字符 58 | \w | 匹配所有字母数字,等同于 `[a-zA-Z0-9_]` 59 | \W | 匹配所有非字母数字,即符号,等同于: `[^\w]` 60 | \d | 匹配数字: `[0-9]` 61 | \D | 匹配非数字: `[^\d]` 62 | \s | 匹配所有空格字符,等同于: `[\t\n\f\r\p{Z}]` 63 | \S | 匹配所有非空格字符: `[^\s]` 64 | \f | 匹配一个换页符 65 | \n | 匹配一个换行符 66 | \r | 匹配一个回车符 67 | \t | 匹配一个制表符 68 | \v | 匹配一个垂直制表符 69 | \p | 匹配 CR/LF(等同于 `\r\n`),用来匹配 DOS 行终止符 70 | \b | 匹配一个单词边界,指单词和空格间的位置。例如,`er\b` 可以匹配 `never` 中的 `er`,但不能匹配 `verb` 中的 `er`。 71 | \B | 匹配非单词边界。`er\B` 能匹配 `verb` 中的 `er`,但不能匹配 `never` 中的 `er`。 72 | 73 |
74 | 75 |
76 | 零宽度断言 77 | 78 | 符号 | 描述 79 | ---- | ---- 80 | ?= | 正先行断言-存在 81 | ?! | 负先行断言-排除 82 | ?<= | 正后发断言-存在 83 | ? 86 | 87 |
88 | 标志 - 模式修正符 89 | 90 | 标志也叫模式修正符,因为它可以用来修改表达式的搜索结果。 91 | 这些标志可以任意的组合使用,它也是整个正则表达式的一部分。 92 | 93 | 标志 | 描述 94 | ---- | ---- 95 | i | 忽略大小写。 96 | g | 全局搜索。 97 | m | 多行修饰符:锚点元字符 `^` `$` 工作范围在每行的起始。 98 | 99 |
100 | 101 | ## 身份证号 102 | 103 | ```regex 104 | ^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$ 105 | ``` 106 | 107 | 🚧 E.g: `42112319870115371X` 108 | 109 | ## 军官证 110 | 111 | ```regex 112 | ^[\u4E00-\u9FA5](字第)([0-9a-zA-Z]{4,8})(号?)$ 113 | ``` 114 | 115 | 🚧 E.g: `军字第2001988号`,`士字第P011816X号`。 军/兵/士/文/职/广/(其他中文) + "字第" + 4到8位字母或数字 + "号" 116 | 117 | ## 护照 118 | 119 | ```regex 120 | ^([a-zA-z]|[0-9]){5,17}$ 121 | ``` 122 | 123 | 🚧 E.g: `141234567`,`G12345678`,`P1234567`。14/15开头 + 7位数字, G + 8位数字, P + 7位数字, S/D + 7或8位数字,等 124 | 125 | ## 统一社会信用代码 126 | 127 | ```regex 128 | ^[1-9ANY][1-59]\d{6}[\dA-Z]{8}[\dX][\dA-HJ-NP-RTUW-Y]$ 129 | ``` 130 | 131 | 🚧 E.g: `92141127MA0KD1Y64A`。[GB 32100-2015](https://zh.wikisource.org/wiki/GB_32100-2015_%E6%B3%95%E4%BA%BA%E5%92%8C%E5%85%B6%E4%BB%96%E7%BB%84%E7%BB%87%E7%BB%9F%E4%B8%80%E7%A4%BE%E4%BC%9A%E4%BF%A1%E7%94%A8%E4%BB%A3%E7%A0%81%E7%BC%96%E7%A0%81%E8%A7%84%E5%88%99)/[法人和其他组织统一社会信用代码制度建设总体方案](https://www.gov.cn/zhengce/content/2015-06/17/content_9858.htm) 132 | 133 | ## 港澳居民来往内地通行证 134 | 135 | ```regex 136 | ^([A-Z]\d{6,10}(\(\w{1}\))?)$ 137 | ``` 138 | 139 | 🚧 E.g: `H1234567890`。H/M + 10位或6位数字 140 | 141 | ## 台湾居民来往大陆通行证 142 | 143 | ```regex 144 | ^\d{8}|^[a-zA-Z0-9]{10}|^\d{18}$ 145 | ``` 146 | 147 | 🚧 E.g: `12345678`,`1234567890B`。新版8位或18位数字, 旧版10位数字 + 英文字母 148 | 149 | ## 用户名 150 | 151 | 152 | ```regex 153 | ^[a-zA-Z0-9_-]{4,16}$ 154 | ``` 155 | 156 | 🚧 E.g: `jaywcjlove`。验证 **数字**、**字母**、**_**、**-**,不包含特殊字符,长度 `4-16` 之间。 157 | 158 | ## 微信号 159 | 160 | ```regex 161 | ^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$ 162 | ``` 163 | 164 | 🚧 E.g: `jslite`。微信号正则,6至20位,以字母开头,字母,数字,减号,下划线。 165 | 166 | ## 密码强度(宽松) 167 | 168 | ```regex 169 | ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$ 170 | ``` 171 | 172 | 🚧 E.g: `diaoD123`, `Wgood123`。必须是包含大小写**字母**和**数字**的组合,长度在 `8-10` 之间。 173 | 174 | ```regex 175 | ^[0-9a-zA-Z\u4E00-\uFA29]*$ 176 | ``` 177 | 178 | 🚧 E.g: `diaoD123`, `Wgood123`。数字字母中文。 179 | 180 | ## 密码强度(包含特殊字符) 181 | 182 | ```regex 183 | ^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$ 184 | ``` 185 | 186 | 🚧 E.g: `diaoD123#`, `Wgood123#$`。密码强度正则,最少`6`位,包括至少`1`个**大写字母**,`1`个**小写字母**,`1`个**数字**,`1`个**特殊字符**。 187 | 188 | ```regex 189 | (?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(.)\1{2})^.{8,22}$ 190 | ``` 191 | 192 | 🚧 相同字符不能出现3次,至少8个,至多22个字符组成,包含一个小写字母,一个大写字母,和一个数字 193 | 194 | ## 火车车次 195 | 196 | ```regex 197 | ^[GCDZTSPKXLY1-9]\d{1,4}$ 198 | ``` 199 | 200 | E.g: `G2868`, `D22`, `D9`, `Z5`, `Z24`, `Z17` 201 | 202 | ## 汉字中文 203 | 204 | ```regex 205 | ^[\u4e00-\u9fa5]{0,}$ 206 | ``` 207 | 208 | 🚧 E.g: `中文`, `湖北`, `黄冈`。不限制文字长度。 209 | 210 | 211 | ```regex 212 | ^[\u4e00-\u9fa5]{2,6}$ 213 | ``` 214 | 215 | 🚧 E.g: `中文`, `湖北黄冈`。2到6位汉字 216 | 217 | ## 中文名字 218 | 219 | ```regex 220 | ^(?:[\u4e00-\u9fa5·]{2,16})$ 221 | ``` 222 | 223 | 🚧 E.g: `周杰伦`, `古丽娜扎尔·拜合提亚尔`, `拉希德·本·穆罕默德·本·拉希德`。 224 | 225 | ## 英文姓名 226 | 227 | ```regex 228 | (^[a-zA-Z][a-zA-Z\s]{0,20}[a-zA-Z]$) 229 | ``` 230 | 231 | 🚧 E.g: `Gene Kelly`, `Fred Astaire`, `Humphrey Bogart`, `GaryCooper`, `Cary Grant`, `Joan Crawford` 232 | 233 | ## URL 234 | 235 | ```regex 236 | ^[a-zA-Z]+:\/\/ 237 | ``` 238 | 239 | 🚧 E.g: `http://www.abc.com`, `http://`, `https://` 240 | 241 | ```regex 242 | ^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$ 243 | ``` 244 | 245 | 🚧 E.g: `https://github.com`, `https://github.com/jaywcjlove` 246 | 247 | ```regex 248 | ^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$ 249 | ``` 250 | 251 | 🚧 E.g: `blog.csdn.net` 252 | 253 | ## Mac地址匹配 254 | 255 | ```regex 256 | ^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$ 257 | ``` 258 | 259 | 🚧 E.g: `dc:a9:04:77:37:20` 260 | 261 | ## 图片后缀 262 | 263 | ```regex 264 | (.jpg|.gif|.png|.jpeg)+(\?|\#|$) 265 | ``` 266 | 267 | 🚧 E.g: `a/b/c.jpg?`, `a/b/c.png`, `a/b/c.png?good=1` 268 | 269 | ## 传真号码 270 | 271 | ```regex 272 | ^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$ 273 | ``` 274 | 275 | 🚧 E.g: `086-021-5055452`, `021-5055452`。国家代码(2到3位),区号(2到3位),电话号码(7到8位),分机号(3位) 276 | 277 | ## 日期(YYYY-MM-DD 格式) 278 | 279 | ```regex 280 | ^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[01])$ 281 | ``` 282 | 283 | 🚧 E.g: `1987-04-03`, `2024-04-28`。月份范围为 01 到 12,日范围分别为 01 到 31、01 到 30、01 到 29(对于闰年的二月)或者 01 到 28 284 | 285 | ## 手机号码 286 | 287 | ```regex 288 | ^1[34578]\d{9}$ 289 | ``` 290 | 291 | 🚧 E.g: `13611778887` 292 | 293 | ```regex 294 | ^((\+?[0-9]{1,4})|(\(\+86\)))?(13[0-9]|14[57]|15[012356789]|17[03678]|18[0-9])\d{8}$ 295 | ``` 296 | 297 | 🚧 E.g: `13611779993`, `+8613611779993` 298 | 299 |
300 | 正则规则详细说明 301 | 302 | * 13段:130、131、132、133、134、135、136、137、138、139 303 | * 14段:145、147 304 | * 15段:150、151、152、153、155、156、157、158、159 305 | * 17段:170、176、177、178 306 | * 18段:180、181、182、183、184、185、186、187、188、189 307 | * 国际码 如:中国(+86) 308 | 309 |
310 | 311 | ## MD5格式(32位) 312 | 313 | ```regex 314 | ^[a-f0-9]{32}$ 315 | ``` 316 | 317 | 🚧 E.g: `a31851770dae6ee96fc886f261c211e7`, `99cd2175108d157588c04758296d1cfc` 318 | 319 | ## IPv4 地址 320 | 321 | ```regex 322 | (\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3} 323 | ``` 324 | 325 | 🚧 E.g: `192.168.1.1`, `127.0.0.1`, `0.0.0.0`, `255.255.255.255`, `1.2.3.4` 326 | 327 | ```regex 328 | ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ 329 | ``` 330 | 331 | 🚧 E.g: `192.168.1.1`, `127.0.0.1`, `0.0.0.0`, `255.255.255.255`, `1.2.3.4` 332 | 333 | ## IPv6 334 | 335 | ```regex 336 | (([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])) 337 | ``` 338 | 339 | 🚧 E.g: `2001:0db8:85a3:0000:0000:8a2e:0370:7334`, `FE80:0000:0000:0000:0202:B3FF:FE1E:8329`。 340 | 341 | ## Email 342 | 343 | ```regex 344 | ^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$ 345 | ``` 346 | 347 | 🚧 E.g: `wowohoo@qq.com` 348 | 349 | ```regex 350 | ^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$ 351 | ``` 352 | 353 | 🚧 E.g: `wowohoo@qq.com` 354 | 355 |
356 | 正则规则详细说明 357 | 358 | 1. 邮箱以a-z、A-Z、0-9开头,最小长度为1. 359 | 2. 如果左侧部分包含-、_、.则这些特殊符号的前面必须包一位数字或字母。 360 | 3. @符号是必填项 361 | 4. 右则部分可分为两部分,第一部分为邮件提供商域名地址,第二部分为域名后缀,现已知的最短为2位。 362 | 最长的为6为。 363 | 5. 邮件提供商域可以包含特殊字符-、_、. 364 | 365 |
366 | 367 | 368 | ## 十六进制颜色 369 | 370 | ```regex 371 | ^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$ 372 | ``` 373 | 374 | 🚧 E.g: `#b8b8b8`, `#333` 375 | 376 | ```regex 377 | ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$ 378 | ``` 379 | 380 | 🚧 E.g: `#b8b8b8`, `#333` 381 | 382 | ## 日期 383 | 384 | ```regex 385 | ^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$ 386 | ``` 387 | 388 | 🚧 E.g: `2017-02-29`。对**月份**及**日期**验证。 389 | 390 | ## 版本号 391 | 392 | ```regex 393 | ^\d+(?:\.\d+){2}$ 394 | ``` 395 | 396 | 🚧 E.g: `0.1.2`。格式必须为 `X.Y.Z`。 397 | 398 | ## 车牌号 399 | 400 | ```regex 401 | ^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](?:((\d{5}[A-HJK])|([A-HJK][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳])$ 402 | ``` 403 | 404 | 🚧 E.g: `鄂A34324`, `沪E13359F`。包含**新能源**车牌。 405 | 406 | ```regex 407 | ^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]$ 408 | ``` 409 | 410 | 🚧 E.g: `鄂A34324`, `沪E13595`。不包含**新能源**车牌。 411 | 412 | ## 小数点后几位 413 | 414 | ```regex 415 | ^(0|[1-9]\d*)(.[0-9]{2})$ 416 | ``` 417 | 418 | 🚧 E.g: `1.22`, ~~`0223.23`~~, ~~`0.00`~~。精确到 `2` 位小数 419 | 420 | 421 | ```regex 422 | ^(?!^0(.0{1,2})?$)\d{0,8}(\.\d{1,2})?$ 423 | ``` 424 | 425 | 🚧 E.g: `99999999.99`, 非零,俩位小数,最大 99999999.99 [@cuilanxin](https://github.com/jaywcjlove/regexp-example/issues/4#issuecomment-1013578631) 426 | 427 | ## 小数 428 | 429 | ```regex 430 | ^\d+\.\d+$ 431 | ``` 432 | 433 | 🚧 E.g: `0.0`, `0.23`, `10.54`。 434 | 435 | ```regex 436 | ^(-?\d+)(\.\d+)?$ 437 | ``` 438 | 439 | 🚧 E.g: `-0.0`, `0.23`, `-10.54`。 440 | 441 | ## 正整数 442 | 443 | ```regex 444 | ^\+?\d+$ 445 | ``` 446 | 447 | 🚧 E.g: `23` 448 | 449 | ## 负整数 450 | 451 | ```regex 452 | ^-?\d+$ 453 | ``` 454 | 455 | 🚧 E.g: `-23`, ~~`-2.34`~~ 456 | 457 | ## 整数 458 | 459 | ```regex 460 | ^\+?-?\d+$ 461 | ``` 462 | 463 | 🚧 E.g: `23`, `12`, `+12`, `-22`, ~~`-12.55`~~ 464 | 465 | ## 非负整数(正整数或零) 466 | 467 | ```regex 468 | ^\d+$ 469 | ``` 470 | 471 | 🚧 E.g: `23`, ~~`3.322`~~ 472 | 473 | ## 数字 474 | 475 | ```regex 476 | ^\d{1,}$ 477 | ``` 478 | 479 | 🚧 E.g: `0120`,`234234`。不包含小数。 480 | 481 | ```regex 482 | ^\d{32}$ 483 | ``` 484 | 485 | 🚧 E.g: `12232324444757575757575757575759`。**32**位纯数字。 486 | 487 | ## 数字(QQ号码) 488 | 489 | ```regex 490 | ^[1-9][0-9]{4,10}$ 491 | ``` 492 | 493 | 🚧 E.g: `398188661`。QQ号正则,5至11位。 494 | 495 | ```regex 496 | ^\d{5,11}$ 497 | ``` 498 | 499 | 🚧 E.g: `398188661`。更简单的 QQ 号码正则,5~11位数字组成。 500 | 501 | 502 | ## 中国邮政编码 503 | 504 | ```regex 505 | ^[1-9]\d{5}$ 506 | ``` 507 | 508 | 🚧 E.g: `200000`。中国邮政编码为 6 位数字。 509 | 510 | ## 英文字母 511 | 512 | ```regex 513 | ^[A-Z]+$ 514 | ``` 515 | 516 | 🚧 E.g: `ABC`,`WANG`。大写英文字母。 517 | 518 | ```regex 519 | ^[a-z]+$ 520 | ``` 521 | 522 | 🚧 E.g: `abc`,`wang`。小写英文字母。 523 | 524 | ```regex 525 | (^[a-z]|[A-Z0-9])[a-z]* 526 | ``` 527 | 528 | 🚧 E.g: `Tests`,`JavaScript`,`RegEx`。大驼峰。 529 | 530 | ## 端口号 531 | 532 | ```regex 533 | ^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$ 534 | ``` 535 | 536 | 🚧 E.g: `8080`,`3000`,`65535` 537 | 538 | ## 迅雷链接 539 | 540 | ```regex 541 | ^thunderx?:\/\/[a-zA-Z\d]+=$ 542 | ``` 543 | 544 | 🚧 E.g: `thunder://QUFodHRwOi0vdG0vbC5sdS90ZXN0LnppcFpa`。 545 | 546 | 547 | ## ed2k链接 548 | 549 | ```regex 550 | ^ed2k:\/\/\|file\|.+\|\/$ 551 | ``` 552 | 553 | 🚧 E.g: `ed2k://|file|[xxx.com][%E8%8B%B1%E9%9B%84%E6%9C%AC%E8%89%B23.mp4|/`。 554 | 555 | ## 磁力链接 556 | 557 | ```regex 558 | ^magnet:\?xt=urn:btih:[0-9a-fA-F]{40,}.*$ 559 | ``` 560 | 561 | 🚧 E.g: `magnet:?xt=urn:btih:608FA22181A2614BAE9160763F04FCB7ED296B9E` 562 | 563 | ## 时间 564 | 565 | ```regex 566 | ^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$ 567 | ``` 568 | 569 | 🚧 E.g: `21:54:55`,`00:23:23`。`24` 小时制时间格式 `HH:mm:ss`,并且验证时间。 570 | 571 | ```regex 572 | ^(?:1[0-2]|0?[1-9]):[0-5]\d:[0-5]\d$ 573 | ``` 574 | 575 | 🚧 E.g: `12:54:55`,`01:23:23`。`12` 小时制时间格式 `HH:mm:ss`,并且验证时间。 576 | 577 | ## HTML标记 578 | 579 | ```regex 580 | <(\S*?)[^>]*>.*?|<.*?/> 581 | ``` 582 | 583 | 🚧 E.g: `
title
`, `title`。 584 | 585 | ## HTML注释 586 | 587 | ```regex 588 | 589 | ``` 590 | 591 | 🚧 E.g: ``。 592 | 593 | ## 工具推荐 594 | 595 | - [RegExp](http://github.com/gskinner/regexr) 线上正则表达式学习利器。 596 | - [Regulex](https://jex.im/regulex/#!flags=&re=%5E(a%7Cb)*%3F%24) JavaScript 正则表达式可视化工具。 [🇨🇳](https://jaywcjlove.gitee.io/regulex/) 597 | - [Rubular](https://rubular.com/) Ruby 正则表达式编辑器。 598 | - [Regex101](https://regex101.com/) 多语言支持、构建、调试并共享正则。 599 | - [Regexper](https://regexper.com/) 正则表达式可视化工具。 600 | - [RegEx Pal](https://www.regexpal.com/) 正则表达式调试及练习示例。 601 | - [Regular Expression Tester](http://myregexp.com/) 在线正则表达式测试仪。 602 | - [iHateRegex](https://github.com/geongeorge/i-hate-regex) 正则表达式备忘清单。 603 | - [以简单的方式学习正则表达式](https://github.com/ziishaned/learn-regex) 604 | - [Expressions APP](https://www.apptorium.com/expressions) 正则表达式应用 for Mac 605 | - [regexlearn.com](https://github.com/aykutkardas/regexlearn.com) 一步一步地学习正则,从零到高级。 606 | - [Regex-Vis](https://github.com/Bowen7/regex-vis) 一个开源的正则表达式可视化编辑器。 607 | 608 | ## Contributors 609 | 610 | As always, thanks to our amazing contributors! 611 | 612 | 613 | 614 | 615 | 616 | Made with [contributors](https://github.com/jaywcjlove/github-action-contributors). 617 | 618 | ## License 619 | 620 | Licensed under the MIT License. 621 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "regexp-example", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "cp -rp regulex dist && idoc -w", 7 | "doc": "cpy regulex dist/ && idoc" 8 | }, 9 | "homepage": "https://jaywcjlove.github.io/regexp-example/", 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/jaywcjlove/regexp-example.git" 13 | }, 14 | "author": "jaywcjlove", 15 | "license": "MIT", 16 | "keywords": [ 17 | "regexp", 18 | "example", 19 | "regexp-example", 20 | "regular-expression", 21 | "learn-regex", 22 | "正则表达式", 23 | "正则", 24 | "regex" 25 | ], 26 | "dependencies": { 27 | "cpy-cli": "^5.0.0", 28 | "fs-extra": "~11.2.0", 29 | "idoc": "^1.31.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /regulex/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Regulex:JavaScript Regular Expression Visualizer 6 | 204 | 205 | 206 | 234 |
235 |
236 | 237 | 238 | 239 | 242 | 243 | 244 | 245 |
/ 240 | 241 | /
246 |
247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 |
255 |

Error Message

256 |
257 | 258 | 265 | 266 | 565 | 566 | 567 | 570 | 576 | 577 | 578 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "packageRules": [ 6 | { 7 | "matchPackagePatterns": ["*"], 8 | "rangeStrategy": "replace" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /scripts/style.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | position: fixed; 3 | border-radius: 2px; 4 | right: 12px; 5 | width: 34px; 6 | font-size: 12px; 7 | color: var(--color-theme-bg); 8 | background-color: var(--color-theme-text); 9 | z-index: 99; 10 | text-align: center; 11 | padding: 3px 0; 12 | line-height: 16px; 13 | text-decoration: initial; 14 | } 15 | .btn:hover { background: #2186ff; color: #fff; } 16 | .btn.create { bottom: 42px; } 17 | .btn.totop { bottom: 12px; } --------------------------------------------------------------------------------