Selaa lähdekoodia

upgrade code-beautify\regexp css styles

zxlie 6 kuukautta sitten
vanhempi
sitoutus
42b4dc9739

+ 3 - 3
apps/background/tools.js

@@ -127,11 +127,11 @@ let toolMap = {
         }]
     },
     'regexp': {
-        name: 'JS正则表达式',
-        tips: '正则校验工具,默认提供一些工作中常用的正则表达式,支持内容实时匹配并高亮显示结果',
+        name: '正则公式速查',
+        tips: '支持 JavaScript / Python / PHP / Java 等语言的正则速查,包含验证类、提取类、替换类、格式化类、特殊字符类、编程相关等常用正则表达式',
         menuConfig: [{
             icon: '✙',
-            text: 'JS正则表达式'
+            text: '正则公式速查'
         }]
     },
     'trans-radix': {

+ 17 - 0
apps/code-beautify/index.css

@@ -6,4 +6,21 @@
 }
 #btnFormat {
     outline: none;
+}
+
+.example-links {
+    margin-left: 70px;
+    display: inline-block;
+}
+
+.example-link {
+    margin-right: 15px;
+    color: #337ab7;
+    text-decoration: none;
+    font-size: 14px;
+}
+
+.example-link:hover {
+    color: #23527c;
+    text-decoration: underline;
 }

+ 7 - 0
apps/code-beautify/index.html

@@ -15,6 +15,13 @@
             <h3 class="panel-title">
                 <a href="https://www.baidufe.com/fehelper/index/index.html" target="_blank" class="x-a-high">
                     <img src="../static/img/fe-16.png" alt="fehelper"/> FeHelper</a>:代码美化 - <span id="codeTitle">{{selectedType}}</span>
+                <span class="example-links">
+                    <a href="javascript:;" @click="loadExample('js',$event)" class="example-link">JS示例</a>
+                    <a href="javascript:;" @click="loadExample('css',$event)" class="example-link">CSS示例</a>
+                    <a href="javascript:;" @click="loadExample('html',$event)" class="example-link">HTML示例</a>
+                    <a href="javascript:;" @click="loadExample('xml',$event)" class="example-link">XML示例</a>
+                    <a href="javascript:;" @click="loadExample('sql',$event)" class="example-link">SQL示例</a>
+                </span>
             </h3>
         </div>
     </div>

+ 28 - 2
apps/code-beautify/index.js

@@ -7,7 +7,14 @@ new Vue({
         selectedType: 'Javascript',
         sourceContent: '',
         resultContent: '',
-        showCopyBtn: false
+        showCopyBtn: false,
+        examples: {
+            js: `function foo(){var x=10;if(x>5){return x*2;}else{return x/2;}}`,
+            css: `.header{position:fixed;top:0;left:0;width:100%;background:#fff;z-index:100;}.header .logo{float:left;margin:10px;}.header .nav{float:right;}`,
+            html: `<div class="container"><div class="header"><h1>标题</h1><nav><ul><li><a href="#">首页</a></li><li><a href="#">关于</a></li></ul></nav></div><div class="content"><p>内容区域</p></div></div>`,
+            xml: `<?xml version="1.0" encoding="UTF-8"?><root><person><name>张三</name><age>25</age><city>北京</city></person><person><name>李四</name><age>30</age><city>上海</city></person></root>`,
+            sql: `SELECT u.name,o.order_id,p.product_name FROM users u LEFT JOIN orders o ON u.id=o.user_id LEFT JOIN products p ON o.product_id=p.id WHERE u.status='active' AND o.create_time>='2024-01-01' ORDER BY o.create_time DESC;`
+        }
     },
 
     mounted: function () {
@@ -79,7 +86,7 @@ new Vue({
                     css_beautify(this.sourceContent, {}, result => beauty(result));
                     break;
                 case 'HTML':
-                    beauty(html_beautify(this.sourceContent,{indent_size:15}));
+                    beauty(html_beautify(this.sourceContent,{indent_size:4}));
                     break;
                 case 'SQL':
                     beauty(vkbeautify.sql(this.sourceContent, 4));
@@ -131,6 +138,25 @@ new Vue({
             window.feHelperAlertMsgTid = window.setTimeout(function () {
                 elAlertMsg.style.display = 'none';
             }, 3000);
+        },
+
+        loadExample(type,event) {
+            if(event){
+                event.preventDefault();
+            }
+            const typeMap = {
+                'js': 'Javascript',
+                'css': 'CSS',
+                'html': 'HTML',
+                'xml': 'XML',
+                'sql': 'SQL'
+            };
+            
+            this.sourceContent = this.examples[type];
+            this.selectedType = typeMap[type];
+            this.$nextTick(() => {
+                this.format();
+            });
         }
     }
 });

+ 54 - 0
apps/code-compress/examples.js

@@ -0,0 +1,54 @@
+const EXAMPLES = {
+    html: `<!DOCTYPE html>
+<html>
+<head>
+    <title>示例页面</title>
+    <meta charset="utf-8">
+</head>
+<body>
+    <div class="container">
+        <h1>这是一个HTML示例</h1>
+        <p>这里包含了一些HTML标签和空格,适合用来测试HTML压缩功能</p>
+    </div>
+</body>
+</html>`,
+    
+    js: `function calculateSum(a, b) {
+    // 这是一个简单的加法函数
+    var result = a + b;
+    
+    // 返回计算结果
+    return result;
+}
+
+// 创建一个数组
+var numbers = [1, 2, 3, 4, 5];
+
+// 使用map方法
+var doubled = numbers.map(function(num) {
+    return num * 2;
+});
+
+console.log(doubled);`,
+    
+    css: `/* 这是一个CSS示例 */
+.container {
+    width: 100%;
+    max-width: 1200px;
+    margin: 0 auto;
+    padding: 20px;
+}
+
+.header {
+    background-color: #f5f5f5;
+    padding: 10px 20px;
+    margin-bottom: 20px;
+}
+
+/* 响应式样式 */
+@media screen and (max-width: 768px) {
+    .container {
+        padding: 10px;
+    }
+}`
+}; 

+ 16 - 0
apps/code-compress/index.css

@@ -41,4 +41,20 @@
     margin: 0 auto;
     font-size: 14px;
     border-bottom: 1px solid #aaa;
+}
+.example-links {
+    display: inline-block;
+    margin-left: 70px;
+}
+
+.example-links a {
+    margin-right: 15px;
+    color: #337ab7;
+    text-decoration: none;
+    font-size: 14px;
+}
+
+.example-links a:hover {
+    color: #23527c;
+    text-decoration: underline;
 }

+ 6 - 0
apps/code-compress/index.html

@@ -15,6 +15,11 @@
                 <h3 class="panel-title">
                     <a href="https://www.baidufe.com/fehelper/index/index.html" target="_blank" class="x-a-high">
                         <img src="../static/img/fe-16.png" alt="fehelper"/> FeHelper</a>:代码压缩工具
+                    <span class="example-links">
+                        <a href="javascript:;" @click="loadExample('html',$event)">html示例</a>
+                        <a href="javascript:;" @click="loadExample('js',$event)">js示例</a>
+                        <a href="javascript:;" @click="loadExample('css',$event)">css示例</a>
+                    </span>
                 </h3>
             </div>
         </div>
@@ -74,6 +79,7 @@
     <script type="text/javascript" src="htmlminifier.min.js"></script>
     <script type="text/javascript" src="index.js"></script>
 
+    <script type="text/javascript" src="examples.js"></script>
     <script src="../static/vendor/jquery/jquery-3.3.1.min.js"></script>
     </body>
 </html>

+ 8 - 0
apps/code-compress/index.js

@@ -155,6 +155,14 @@ new Vue({
             document.body.removeChild(input);
 
             this.toast('压缩结果已复制成功,随处粘贴可用!');
+        },
+        loadExample(type,event) {
+            if(event){
+                event.preventDefault();
+            }
+            this.codeType = type;
+            editor.setValue(EXAMPLES[type]);
+            this.changeCodeType(type);
         }
     }
 });

+ 1 - 1
apps/manifest.json

@@ -88,7 +88,7 @@
     }
   ],
   "content_security_policy": {
-      "extension_pages": "script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'self'"
+    "extension_pages": "script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; object-src 'self'"
   },
   "update_url": "https://clients2.google.com/service/update2/crx",
   "homepage_url": "https://www.baidufe.com/fehelper"

+ 1 - 1
apps/popup/index.css

@@ -37,7 +37,7 @@ ul.fe-function-list {
 }
 
 ul.fe-function-list li {
-    padding: 2px 16px 2px 40px;
+    padding: 2px 10px 2px 38px;
     cursor: pointer;
     color: #4a4c6d;
     transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);

+ 1 - 1
apps/postman/index.html

@@ -1,5 +1,5 @@
 <!DOCTYPE HTML>
-<html lang="zh-CN">
+<html lang="zh-CN" class="fh-jf">
     <head>
         <title>简易版Postman</title>
         <meta charset="UTF-8">

+ 363 - 112
apps/regexp/index.css

@@ -1,112 +1,363 @@
-@import url("../static/css/bootstrap.min.css");
-
-html {
-    font-size:14px
-}
-body {
-    color:#666
-}
-.pannel-select{
-    position: absolute;
-    right: 0;
-    top: 0;
-    width: 255px;
-    height: 30px;
-}
-.reglist_select{
-    padding: 0 0;
-    height: 24px;
-}
-.reg_link{
-    display: inline-block;
-    float: right;
-    text-align: right;
-    font-size: 12px;
-    margin-top: 4px;
-}
-.reg_pre{
-    border: none;
-    background: transparent;
-}
-.reg_reg_input{
-    resize:none;
-}
-.reg_textarea{
-    padding: 0;
-    width: 100%;
-    resize: none;
-    font: 100%"courier new", monospace;
-}
-#srcWrapper{
-    padding: 12px;
-}
-.wrapper #srcBackground{
-    padding: 0;
-}
-.mod-regexp {
-    margin: 0 auto;
-    padding: 0;
-    background: #FFF;
-}
-#srcWrapper {
-    background:#fff;
-    border:1px solid #ccc;
-    min-height:50px;
-    position:relative;
-    border-radius: 4px;
-    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-    -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
-    -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
-    transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
-}
-
-#srcBackground {
-    padding:4px;
-    margin:0;
-    position:absolute;
-    z-index:1;
-    width:100%;
-    word-break: break-all;
-    line-height:14px;
-}
-#srcBackground i, #srcBackground b {
-    font: 100% "courier new",monospace;
-    font-style:normal;
-    font-weight:normal;
-    font-size:14px;
-    margin:0;
-    padding:0;
-    background:#fff;
-    color:#fff
-}
-#srcBackground b {
-    background:#dd0;
-    color:#dd0
-}
-#srcCode {
-    background:transparent;
-    margin:0;
-    border:none;
-    font-size:14px;
-    position:relative;
-    z-index:2;
-    outline:none;
-    overflow-y:hidden
-}
-
-#rstCount {
-    color:#f00
-}
-#rstCode {
-    padding:3px
-}
-#regTip {
-    font-size:12px;
-    color:#d00;
-    display:none
-}
-.x-tip {
-    font-size:12px;
-    color:#00b
-}
+/* 全局样式 */
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+}
+
+body {
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+    background-color: #f5f6fa;
+    color: #2c3e50;
+    line-height: 1.4;
+}
+
+/* 头部样式 */
+.header {
+    background-color: #fff;
+    padding: 0.8rem 1.5rem;
+    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+    position: sticky;
+    top: 0;
+    z-index: 100;
+}
+
+.logo {
+    display: flex;
+    align-items: center;
+    gap: 0.8rem;
+}
+
+.logo h1 {
+    font-size: 1.2rem;
+    margin: 0;
+}
+
+.subtitle {
+    color: #3498db;
+    font-size: 0.9rem;
+    margin-left: 0.5rem;
+    padding: 0.2rem 0.5rem;
+    background-color: rgba(52, 152, 219, 0.1);
+    border-radius: 4px;
+}
+
+/* 主容器样式 */
+.container {
+    max-width: 1200px;
+    margin: 0.5rem auto;
+    padding: 0 0.5rem;
+}
+
+/* 正则分类样式 */
+.regex-categories {
+    column-count: 3;
+    column-gap: 0.5rem;
+    margin: 0 auto;
+}
+
+.category {
+    background: #fff;
+    border-radius: 8px;
+    padding: 0.8rem;
+    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+    break-inside: avoid;
+    margin-bottom: 0.5rem;
+    page-break-inside: avoid;
+    -webkit-column-break-inside: avoid;
+}
+
+.category h2 {
+    font-size: 1rem;
+    color: #2c3e50;
+    margin-bottom: 0.5rem;
+    padding-bottom: 0.3rem;
+    border-bottom: 2px solid #3498db;
+}
+
+.regex-list {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+    gap: 0.5rem;
+}
+
+/* 正则项目和工具提示样式 */
+.regex-item {
+    padding: 0.5rem;
+    background-color: #f8f9fa;
+    border: 1px solid #e9ecef;
+    border-radius: 4px;
+    cursor: pointer;
+    font-size: 0.9rem;
+    transition: all 0.2s ease;
+    text-align: center;
+    position: relative;
+}
+
+.regex-item:hover {
+    background-color: #3498db;
+    color: #fff;
+    transform: translateY(-1px);
+    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+
+/* 工具提示气泡 */
+.regex-item::after {
+    content: "点击获取正则表达式";
+    position: absolute;
+    bottom: 100%;
+    left: 50%;
+    transform: translateX(-50%);
+    padding: 0.4rem 0.8rem;
+    background-color: #2c3e50;
+    color: #fff;
+    font-size: 0.8rem;
+    border-radius: 4px;
+    white-space: nowrap;
+    opacity: 0;
+    visibility: hidden;
+    transition: all 0.2s ease;
+    z-index: 10;
+    pointer-events: none;
+}
+
+/* 工具提示三角形 */
+.regex-item::before {
+    content: "";
+    position: absolute;
+    bottom: 100%;
+    left: 50%;
+    transform: translateX(-50%);
+    border: 6px solid transparent;
+    border-top-color: #2c3e50;
+    opacity: 0;
+    visibility: hidden;
+    transition: all 0.2s ease;
+    z-index: 10;
+    pointer-events: none;
+}
+
+/* 显示工具提示 */
+.regex-item:hover::after {
+    opacity: 1;
+    visibility: visible;
+    bottom: calc(100% + 10px);
+}
+
+.regex-item:hover::before {
+    opacity: 1;
+    visibility: visible;
+    bottom: calc(100% + 4px);
+}
+
+/* 模态框样式 */
+.modal {
+    display: none;
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0,0,0,0.5);
+    z-index: 1000;
+}
+
+.modal-content {
+    position: relative;
+    background-color: #fff;
+    margin: 2rem auto;
+    padding: 1.5rem;
+    width: 700px;
+    max-width: 800px;
+    border-radius: 8px;
+    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
+    max-height: calc(100vh - 4rem);
+    overflow-y: auto;
+}
+
+.close {
+    position: absolute;
+    right: 1rem;
+    top: 1rem;
+    font-size: 1.5rem;
+    cursor: pointer;
+    color: #666;
+}
+
+.close:hover {
+    color: #e74c3c;
+}
+
+.regex-versions {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
+    gap: 1rem;
+    margin: 1rem 0;
+}
+
+.version {
+    background-color: #f8f9fa;
+    padding: 0.8rem;
+    border-radius: 4px;
+}
+
+.version h3 {
+    font-size: 0.9rem;
+    margin-bottom: 0.5rem;
+    color: #2c3e50;
+}
+
+pre {
+    background-color: #fff;
+    padding: 0.5rem;
+    border-radius: 4px;
+    border: 1px solid #e9ecef;
+    font-size: 0.85rem;
+    overflow-x: auto;
+}
+
+.copy-btn {
+    margin-top: 0.5rem;
+    padding: 0.3rem 0.8rem;
+    background-color: #3498db;
+    color: #fff;
+    border: none;
+    border-radius: 4px;
+    cursor: pointer;
+    font-size: 0.85rem;
+    transition: background-color 0.2s;
+}
+
+.copy-btn:hover {
+    background-color: #2980b9;
+}
+
+.regex-description {
+    margin-top: 1rem;
+    padding-top: 1rem;
+    border-top: 1px solid #e9ecef;
+}
+
+.regex-description h3 {
+    font-size: 0.9rem;
+    margin-bottom: 0.5rem;
+    color: #2c3e50;
+}
+
+.regex-description p {
+    font-size: 0.9rem;
+    color: #666;
+    line-height: 1.5;
+}
+
+/* 响应式调整 */
+@media (max-width: 1024px) {
+    .regex-categories {
+        column-count: 2;
+    }
+}
+
+@media (max-width: 768px) {
+    .regex-categories {
+        column-count: 1;
+    }
+    .regex-list {
+        grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
+    }
+    .regex-versions {
+        grid-template-columns: 1fr;
+    }
+    .modal-content {
+        width: 95%;
+        margin: 1rem auto;
+    }
+    .subtitle {
+        display: none;
+    }
+    .container {
+        padding: 0 0.3rem;
+    }
+    /* 移动端工具提示调整 */
+    .regex-item::after {
+        display: none;
+    }
+    
+    .regex-item::before {
+        display: none;
+    }
+}
+
+.search-container {
+    width: 100%;
+    padding: 10px 0;
+    display: flex;
+    justify-content: center;
+    margin-bottom: 10px;
+}
+
+.search-box {
+    position: relative;
+    width: 60%;
+    max-width: 600px;
+}
+
+.search-box input {
+    width: 100%;
+    padding: 15px 45px 15px 20px;
+    border: 2px solid #3498db;
+    border-radius: 25px;
+    font-size: 16px;
+    transition: all 0.3s ease;
+    outline: none;
+    background-color: rgba(255, 255, 255, 0.9);
+    box-shadow: 0 4px 6px rgba(52, 152, 219, 0.1);
+}
+
+.search-box input:focus {
+    border-color: #2980b9;
+    box-shadow: 0 4px 12px rgba(52, 152, 219, 0.2);
+    background-color: #ffffff;
+    transform: translateY(-1px);
+}
+
+.search-box input::placeholder {
+    color: #95a5a6;
+}
+
+.search-box .search-icon {
+    position: absolute;
+    right: 20px;
+    top: 50%;
+    transform: translateY(-50%);
+    color: #3498db;
+    font-size: 20px;
+    pointer-events: none;
+    transition: all 0.3s ease;
+}
+
+.search-box input:focus + .search-icon {
+    color: #2980b9;
+}
+
+/* 搜索结果高亮样式 */
+.regex-item.highlight {
+    background-color: #fff3cd;
+    border-color: #3498db;
+    box-shadow: 0 2px 4px rgba(52, 152, 219, 0.15);
+    transform: translateY(-1px);
+}
+
+.regex-item.hidden {
+    display: none;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+    .search-box {
+        width: 90%;
+    }
+    
+    .search-container {
+        padding: 15px 0;
+    }
+}

+ 141 - 82
apps/regexp/index.html

@@ -1,96 +1,155 @@
-<!DOCTYPE HTML>
+<!DOCTYPE html>
 <html lang="zh-CN">
     <head>
-        <title>正则表达式工具</title>
         <meta charset="UTF-8">
-        <link rel="shortcut icon" href="../static/img/favicon.ico">
-        <link rel="stylesheet" href="index.css" />
-        <script type="text/javascript" src="../static/vendor/evalCore.min.js"></script>
-        <script type="text/javascript" src="../static/vendor/jquery/jquery-3.3.1.min.js"></script>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <title>正则表达式工具 - FeHelper</title>
+        <link rel="stylesheet" href="index.css">
     </head>
     <body>
-        <div class="wrapper" id="pageContainer">
-            <div class="panel panel-default" style="margin-bottom: 0px;">
-                <div class="panel-heading">
-                    <h3 class="panel-title">
-                        <a href="https://www.baidufe.com/fehelper/index/index.html" target="_blank" class="x-a-high">
-                            <img src="../static/img/fe-16.png" alt="fehelper"/> FeHelper</a>:正则表达式工具</h3>
-                </div>
+        <header class="header">
+            <div class="logo">
+                <img src="../../static/img/fe-48.png" alt="FeHelper Logo" width="24" height="24">
+                <h3>FeHelper | 正则表达式速查</h3>
+                <span class="subtitle">支持 JavaScript / Python / PHP / Java 等语言的正则速查</span>
             </div>
-            <div class="panel-body mod-regexp">
-                <div class="ui-po-r ui-mb-20">
-                    <h3 class="panel-subtitle">正则表达式</h3>
-                <span class="pannel-select reg-list">
-                    <select class="form-control reglist_select" id="regList">
-                        <option value="">-- 常用正则表达式 --</option>
-                        <optgroup label="常用字符">
-                            <option value="/[\u4e00-\u9fa5]/gm">匹配中文字符</option>
-                            <option value="/[^\x00-\xff]/igm">匹配双字节字符</option>
-                            <option value="/(^\s*)|(\s*$)/">匹配行尾行首空白</option>
-                            <option value="/^\d+$/">只能输入数字</option>
-                            <option value="/^\d{n}$/">只能输入n个数字</option>
-                            <option value="/^\d{n,}$/">至少输入n个以上的数字</option>
-                            <option value="/^\d{m,n}$/">只能输入m到n个数字</option>
-                            <option value="/^[a-z]+$/i">只能由英文字母组成</option>
-                            <option value="/^[A-Z]+$/">只能由大写英文字母组成</option>
-                            <option value="/^[a-z0-9]+$/i">只能由英文和数字组成</option>
-                            <option value="/^\w+$/">只能由英文、数字、下划线组成</option>
-                        </optgroup>
-                        <optgroup label="常用表单">
-                            <option value="/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/">匹配Email地址</option>
-                            <option value="/^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i">匹配URL地址</option>
-                            <option value="/^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/">匹配手机号码</option>
-                            <option value="/^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/">匹配身份证号</option>
-                            <option value="/^[1-9]\d{5}(?!\d)$/">匹配邮编号</option>
-                            <option value="/^[1-2][0-9][0-9][0-9]-[0-1]{0,1}[0-9]-[0-3]{0,1}[0-9]$/">匹配日期(yyyy-MM-dd)</option>
-                            <option value="/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z][A-Z0-9]{4}[A-Z0-9挂学警港澳]$/">匹配车牌号(蓝牌)</option>
-                            <option value="/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z][A-Z0-9]{5}[A-Z0-9挂学警港澳]$/">匹配车牌号(绿牌)</option>
-                        </optgroup>
-                        <optgroup label="浏览器navigator.userAgent">
-                            <option value="/msie (\d+\.\d+)/i">从UA判断是否为IE浏览器</option>
-                            <option value="/webkit/i">从UA判断是否为webkit内核</option>
-                            <option value="/chrome\/(\d+\.\d+)/i">从UA判断是否为chrome浏览器</option>
-                            <option value="/firefox\/(\d+\.\d+)/i">从UA判断是否为firefox浏览器</option>
-                            <option value="/opera(\/| )(\d+(\.\d+)?)(.+?(version\/(\d+(\.\d+)?)))?/i">从UA判断是否为opera浏览器</option>
-                            <option value="/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i">从UA判断是否为Safari浏览器</option>
-                            <option value="/android/i">从UA中判断是否为Android系统</option>
-                            <option value="/ipad/i">从UA中判断是否为iPad</option>
-                            <option value="/iphone/i">从UA中判断是否为iPhone</option>
-                            <option value="/macintosh/i">从UA判断是否为Mac OS平台</option>
-                            <option value="/windows/i">从UA中判断是否为Windows平台</option>
-                            <option value="/(nokia|iphone|android|ipad|motorola|^mot\-|softbank|foma|docomo|kddi|up\.browser|up\.link|htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam\-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte\-|longcos|pantech|gionee|^sie\-|portalmmm|jig\s browser|hiptop|^ucweb|^benq|haier|^lct|opera\s*mobi|opera\*mini|320x320|240x320|176x220)/i">从UA中判断是否为移动终端</option>
-                        </optgroup>
-                        <optgroup label="HTML相关">
-                            <option value="/\<link\s(.*?)\s*(([^&]>)|(\/\>)|(\<\/link\>))/gi">匹配link标签</option>
-                            <option value="/<(\S*?) [^>]*>.*?</\1>|<.*?/>/gm">匹配HTML标签</option>
-                            <option value="/^[^<>`~!/@\#}$%:;)(_^{&*=|'+]+$/">匹配非HTML标签</option>
-                            <option value="/<script[^>]*>[\s\S]*?<\/[^>]*script>/gi">匹配script标签</option>
-                            <option value="/<!--[\s\S]*?--\>/g">匹配HTML注释</option>
-                            <option value="/\[\s*if\s+[^\]][\s\w]*\]/i">匹配HTML条件注释</option>
-                            <option value="/^\[if\s+(!IE|false)\]>.*<!\[endif\]$/i">匹配非IE的条件注释</option>
-                            <option value="/expression[\s\r\n ]?\(/gi">匹配CSS expression</option>
-                            <option value="/<\W+>/gi">匹配不合法的HTML标签</option>
-                            <option value="/<textarea[^>]*>[\s\S]*?<\/[^>]*textarea>/gi">匹配textarea标签</option>
-                        </optgroup>
-                    </select>
-                </span>
+        </header>
+
+        <main class="container">
+            <div class="search-container">
+                <div class="search-box">
+                    <input type="text" id="regexSearch" placeholder="搜索正则表达式..." />
+                    <span class="search-icon">🔍</span>
                 </div>
-                <textarea class="reg_reg_input form-control" id="regText" placeholder="输入正则表达式,如:/[0-9A-Z].*?/igm" rows="1" tabindex="10"></textarea>
-                <a class="reg_link" href="http://www.baidufe.com/item/eb10deb92f2c05ca32cf.html" target="_blank" tabindex="30">Javascript正则表达式语法</a>
+            </div>
+            
+            <div class="regex-categories">
+                <!-- 验证类 -->
+                <section class="category">
+                    <h2>验证类</h2>
+                    <div class="regex-list">
+                        <div class="regex-item" data-regex-id="email">邮箱验证</div>
+                        <div class="regex-item" data-regex-id="phone">手机号验证</div>
+                        <div class="regex-item" data-regex-id="tel">固定电话验证</div>
+                        <div class="regex-item" data-regex-id="url">URL验证</div>
+                        <div class="regex-item" data-regex-id="idcard">身份证验证</div>
+                        <div class="regex-item" data-regex-id="ipv4">IPv4地址验证</div>
+                        <div class="regex-item" data-regex-id="date">日期验证</div>
+                        <div class="regex-item" data-regex-id="number">数字验证</div>
+                        <div class="regex-item" data-regex-id="number-n-digits">n位数字验证</div>
+                        <div class="regex-item" data-regex-id="number-min-n-digits">至少n位数字验证</div>
+                        <div class="regex-item" data-regex-id="number-range-digits">数字位数范围验证</div>
+                        <div class="regex-item" data-regex-id="decimal">小数验证</div>
+                        <div class="regex-item" data-regex-id="integer">整数验证</div>
+                        <div class="regex-item" data-regex-id="chinese-name">中文姓名验证</div>
+                        <div class="regex-item" data-regex-id="english-name">英文姓名验证</div>
+                        <div class="regex-item" data-regex-id="username">用户名验证</div>
+                        <div class="regex-item" data-regex-id="password-strong">强密码验证</div>
+                        <div class="regex-item" data-regex-id="mac-address">MAC地址验证</div>
+                        <div class="regex-item" data-regex-id="hex-color">16进制颜色验证</div>
+                        <div class="regex-item" data-regex-id="version-number">版本号验证</div>
+                    </div>
+                </section>
+
+                <!-- 提取类 -->
+                <section class="category">
+                    <h2>提取类</h2>
+                    <div class="regex-list">
+                        <div class="regex-item" data-regex-id="html-tag">HTML标签提取</div>
+                        <div class="regex-item" data-regex-id="img-url">图片URL提取</div>
+                        <div class="regex-item" data-regex-id="chinese">中文字符提取</div>
+                        <div class="regex-item" data-regex-id="numbers">数字提取</div>
+                        <div class="regex-item" data-regex-id="email-extract">邮箱地址提取</div>
+                        <div class="regex-item" data-regex-id="link-extract">链接提取</div>
+                        <div class="regex-item" data-regex-id="color-hex">颜色值提取</div>
+                        <div class="regex-item" data-regex-id="ip-extract">IP地址提取</div>
+                    </div>
+                </section>
+
+                <!-- 替换类 -->
+                <section class="category">
+                    <h2>替换类</h2>
+                    <div class="regex-list">
+                        <div class="regex-item" data-regex-id="trim">去除首尾空格</div>
+                        <div class="regex-item" data-regex-id="remove-html">去除HTML标签</div>
+                        <div class="regex-item" data-regex-id="camelcase">驼峰命名转换</div>
+                        <div class="regex-item" data-regex-id="remove-script">去除Script标签</div>
+                        <div class="regex-item" data-regex-id="remove-space">去除多余空格</div>
+                        <div class="regex-item" data-regex-id="remove-comment">去除注释</div>
+                    </div>
+                </section>
+
+                <!-- 格式化类 -->
+                <section class="category">
+                    <h2>格式化类</h2>
+                    <div class="regex-list">
+                        <div class="regex-item" data-regex-id="money">金额格式化</div>
+                        <div class="regex-item" data-regex-id="phone-format">手机号格式化</div>
+                        <div class="regex-item" data-regex-id="date-format">日期格式化</div>
+                        <div class="regex-item" data-regex-id="card-format">银行卡格式化</div>
+                        <div class="regex-item" data-regex-id="idcard-format">身份证格式化</div>
+                    </div>
+                </section>
 
-                <div id="src" class="ui-mt-20">
-                    <h3 class="panel-subtitle">文本内容</h3>
-                    <div id="srcWrapper">
-                        <pre class="reg_pre" id="srcBackground"></pre>
-                        <textarea class="reg_textarea" id="srcCode" placeholder="输入待匹配的文本" contenteditable="true"></textarea>
+                <!-- 特殊字符类 -->
+                <section class="category">
+                    <h2>特殊字符类</h2>
+                    <div class="regex-list">
+                        <div class="regex-item" data-regex-id="emoji">Emoji表情</div>
+                        <div class="regex-item" data-regex-id="special-char">特殊字符</div>
+                        <div class="regex-item" data-regex-id="unicode">Unicode字符</div>
+                        <div class="regex-item" data-regex-id="invisible-char">不可见字符</div>
+                    </div>
+                </section>
+
+                <!-- 编程相关 -->
+                <section class="category">
+                    <h2>编程相关</h2>
+                    <div class="regex-list">
+                        <div class="regex-item" data-regex-id="variable">变量命名</div>
+                        <div class="regex-item" data-regex-id="function">函数声明</div>
+                        <div class="regex-item" data-regex-id="json">JSON格式</div>
+                        <div class="regex-item" data-regex-id="xml">XML标签</div>
+                        <div class="regex-item" data-regex-id="css">CSS选择器</div>
+                    </div>
+                </section>
+            </div>
+        </main>
+
+        <!-- 模态框 -->
+        <div class="modal" id="regexModal">
+            <div class="modal-content">
+                <span class="close">&times;</span>
+                <h2 id="modalTitle"></h2>
+                <div class="regex-versions">
+                    <div class="version">
+                        <h3>JavaScript</h3>
+                        <pre><code id="jsRegex"></code></pre>
+                        <button class="copy-btn" data-target="jsRegex">复制</button>
+                    </div>
+                    <div class="version">
+                        <h3>Python</h3>
+                        <pre><code id="pythonRegex"></code></pre>
+                        <button class="copy-btn" data-target="pythonRegex">复制</button>
+                    </div>
+                    <div class="version">
+                        <h3>PHP</h3>
+                        <pre><code id="phpRegex"></code></pre>
+                        <button class="copy-btn" data-target="phpRegex">复制</button>
+                    </div>
+                    <div class="version">
+                        <h3>Java</h3>
+                        <pre><code id="javaRegex"></code></pre>
+                        <button class="copy-btn" data-target="javaRegex">复制</button>
                     </div>
                 </div>
-                <div id="rst" class="">
-                    <h3 class="panel-subtitle">匹配结果&nbsp;&nbsp;<span id="rstCount"></span></h3>
-                    <div id="rstCode"></div>
+                <div class="regex-description">
+                    <h3>说明</h3>
+                    <p id="regexDescription"></p>
                 </div>
             </div>
         </div>
-        <script type="text/javascript" src="index.js"></script>
+
+        <script src="index.js"></script>
     </body>
-</html>
+</html>

+ 602 - 212
apps/regexp/index.js

@@ -1,220 +1,610 @@
-/**
- * FeHelper 正则工具
- */
-
-/**
- * 自适应高度的jquery插件
- */
-$.fn.extend({
-    textareaAutoHeight:function (options) {
-        this._options = {
-            minHeight:0,
-            maxHeight:100000
-        };
-
-        this.init = function () {
-            for (var p in options) {
-                this._options[p] = options[p];
-            }
-            if (this._options.minHeight === 0) {
-                this._options.minHeight = parseFloat($(this).height());
-            }
-            for (var p in this._options) {
-                if ($(this).attr(p) == null) {
-                    $(this).attr(p, this._options[p]);
-                }
-            }
-            $(this).keyup(this.resetHeight).change(this.resetHeight)
-                .focus(this.resetHeight);
-        };
-        this.resetHeight = function () {
-            var _minHeight = parseFloat($(this).attr("minHeight"));
-            var _maxHeight = parseFloat($(this).attr("maxHeight"));
-
-            $(this).height(0);
-            var h = parseFloat(this.scrollHeight);
-            h = h < _minHeight ? _minHeight :
-                h > _maxHeight ? _maxHeight : h;
-            $(this).height(h).scrollTop(h);
-            if (h >= _maxHeight) {
-                $(this).css("overflow-y", "scroll");
-            }
-            else {
-                $(this).css("overflow-y", "hidden");
-            }
-        };
-        this.init();
+// 正则表达式数据库
+const regexDatabase = {
+    // 验证类
+    'email': {
+        title: '邮箱验证',
+        description: '验证电子邮箱地址的合法性,支持@前的各种字符组合,@后必须是域名格式',
+        patterns: {
+            javascript: '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/',
+            python: 'r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"',
+            php: '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/',
+            java: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'
+        }
+    },
+    'phone': {
+        title: '手机号验证',
+        description: '验证中国大陆手机号码,支持最新号段',
+        patterns: {
+            javascript: '/^1[3-9]\\d{9}$/',
+            python: 'r"^1[3-9]\\d{9}$"',
+            php: '/^1[3-9]\\d{9}$/',
+            java: '^1[3-9]\\d{9}$'
+        }
+    },
+    'tel': {
+        title: '固定电话验证',
+        description: '验证固定电话号码,支持区号+号码的格式',
+        patterns: {
+            javascript: '/^(0\\d{2,3}-?)?\\d{7,8}$/',
+            python: 'r"^(0\\d{2,3}-?)?\\d{7,8}$"',
+            php: '/^(0\\d{2,3}-?)?\\d{7,8}$/',
+            java: '^(0\\d{2,3}-?)?\\d{7,8}$'
+        }
+    },
+    'password': {
+        title: '密码强度验证',
+        description: '密码必须包含大小写字母、数字和特殊字符,长度8-16位',
+        patterns: {
+            javascript: '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$/',
+            python: 'r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$"',
+            php: '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$/',
+            java: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$'
+        }
+    },
+    'qq': {
+        title: 'QQ号验证',
+        description: '验证QQ号,必须是5-11位数字,首位不能为0',
+        patterns: {
+            javascript: '/^[1-9][0-9]{4,10}$/',
+            python: 'r"^[1-9][0-9]{4,10}$"',
+            php: '/^[1-9][0-9]{4,10}$/',
+            java: '^[1-9][0-9]{4,10}$'
+        }
+    },
+    'postal': {
+        title: '邮政编码验证',
+        description: '验证中国邮政编码,6位数字',
+        patterns: {
+            javascript: '/^\\d{6}$/',
+            python: 'r"^\\d{6}$"',
+            php: '/^\\d{6}$/',
+            java: '^\\d{6}$'
+        }
+    },
+    'account': {
+        title: '账号验证',
+        description: '验证账号,字母开头,允许5-16位,字母数字下划线组合',
+        patterns: {
+            javascript: '/^[a-zA-Z]\\w{4,15}$/',
+            python: 'r"^[a-zA-Z]\\w{4,15}$"',
+            php: '/^[a-zA-Z]\\w{4,15}$/',
+            java: '^[a-zA-Z]\\w{4,15}$'
+        }
+    },
+    'url': {
+        title: 'URL验证',
+        description: '验证URL地址的合法性,支持http、https协议',
+        patterns: {
+            javascript: '/^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([\\/\\w .-]*)*\\/?$/',
+            python: 'r"^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([\\/\\w .-]*)*\\/?$"',
+            php: '/^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([\\/\\w .-]*)*\\/?$/',
+            java: '^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([\\/\\w .-]*)*\\/?$'
+        }
+    },
+    'idcard': {
+        title: '身份证验证',
+        description: '验证中国大陆居民身份证号码,支持18位',
+        patterns: {
+            javascript: '/^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9X]$/',
+            python: 'r"^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9X]$"',
+            php: '/^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9X]$/',
+            java: '^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9X]$'
+        }
+    },
+    'ipv4': {
+        title: 'IPv4地址验证',
+        description: '验证IPv4地址格式',
+        patterns: {
+            javascript: '/^((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]?)$/',
+            python: 'r"^((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]?)$"',
+            php: '/^((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]?)$/',
+            java: '^((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]?)$'
+        }
+    },
+    'date': {
+        title: '日期验证',
+        description: '验证日期格式(YYYY-MM-DD)',
+        patterns: {
+            javascript: '/^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$/',
+            python: 'r"^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$"',
+            php: '/^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$/',
+            java: '^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$'
+        }
+    },
+
+    // 提取类
+    'html-tag': {
+        title: 'HTML标签提取',
+        description: '提取HTML标签及其内容',
+        patterns: {
+            javascript: '/<([a-z][a-z0-9]*)[^>]*>.*?<\\/\\1>/gi',
+            python: 'r"<([a-z][a-z0-9]*)[^>]*>.*?</\\1>"',
+            php: '/<([a-z][a-z0-9]*)[^>]*>.*?<\\/\\1>/i',
+            java: '<([a-z][a-z0-9]*)[^>]*>.*?</\\1>'
+        }
+    },
+    'img-url': {
+        title: '图片URL提取',
+        description: '提取HTML中的图片URL',
+        patterns: {
+            javascript: '/<img[^>]+src="([^">]+)"/gi',
+            python: 'r"<img[^>]+src=\\"([^\\">]+)\\""',
+            php: '/<img[^>]+src="([^">]+)"/i',
+            java: '<img[^>]+src="([^">]+)"'
+        }
+    },
+    'chinese': {
+        title: '中文字符提取',
+        description: '提取中文字符',
+        patterns: {
+            javascript: '/[\\u4e00-\\u9fa5]/g',
+            python: 'r"[\\u4e00-\\u9fa5]"',
+            php: '/[\\x{4e00}-\\x{9fa5}]/u',
+            java: '[\\u4e00-\\u9fa5]'
+        }
+    },
+    'numbers': {
+        title: '数字提取',
+        description: '提取字符串中的数字',
+        patterns: {
+            javascript: '/\\d+(\\.\\d+)?/g',
+            python: 'r"\\d+(\\.\\d+)?"',
+            php: '/\\d+(\\.\\d+)?/',
+            java: '\\d+(\\.\\d+)?'
+        }
+    },
+    'email-extract': {
+        title: '邮箱地址提取',
+        description: '提取文本中的邮箱地址',
+        patterns: {
+            javascript: '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g',
+            python: 'r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"',
+            php: '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/',
+            java: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}'
+        }
+    },
+    'color-hex': {
+        title: '颜色值提取',
+        description: '提取16进制颜色值,支持3位和6位格式',
+        patterns: {
+            javascript: '/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g',
+            python: 'r"#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})"',
+            php: '/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/i',
+            java: '#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})'
+        }
+    },
+    'ip-extract': {
+        title: 'IP地址提取',
+        description: '提取IPv4地址',
+        patterns: {
+            javascript: '/\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g',
+            python: 'r"\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b"',
+            php: '/\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/',
+            java: '\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b'
+        }
+    },
+
+    // 替换类
+    'trim': {
+        title: '去除首尾空格',
+        description: '去除字符串首尾的空白字符',
+        patterns: {
+            javascript: '/^\\s+|\\s+$/g',
+            python: 'r"^\\s+|\\s+$"',
+            php: '/^\\s+|\\s+$/',
+            java: '^\\s+|\\s+$'
+        }
+    },
+    'remove-html': {
+        title: '去除HTML标签',
+        description: '去除文本中的HTML标签',
+        patterns: {
+            javascript: '/<[^>]+>/g',
+            python: 'r"<[^>]+>"',
+            php: '/<[^>]+>/',
+            java: '<[^>]+>'
+        }
+    },
+    'remove-script': {
+        title: '去除Script标签',
+        description: '去除HTML中的script标签及其内容',
+        patterns: {
+            javascript: '/<script[^>]*>[\\s\\S]*?<\\/script>/gi',
+            python: 'r"<script[^>]*>[\\s\\S]*?</script>"',
+            php: '/<script[^>]*>[\\s\\S]*?<\\/script>/i',
+            java: '<script[^>]*>[\\s\\S]*?</script>'
+        }
+    },
+    'remove-space': {
+        title: '去除多余空格',
+        description: '去除字符串中的多余空格,保留单个空格',
+        patterns: {
+            javascript: '/\\s+/g',
+            python: 'r"\\s+"',
+            php: '/\\s+/',
+            java: '\\s+'
+        }
+    },
+    'remove-comment': {
+        title: '去除注释',
+        description: '去除代码中的单行和多行注释',
+        patterns: {
+            javascript: '/(\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/)/gm',
+            python: 'r"(#.*$)|(\'\'\'[\\s\\S]*?\'\'\')|(\\"\\"\\"[\\s\\S]*?\\"\\"\\"))"',
+            php: '/(\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/)/m',
+            java: '(/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)'
+        }
+    },
+
+    // 格式化类
+    'money': {
+        title: '金额格式化',
+        description: '将数字转换为金额格式(每三位加逗号)',
+        patterns: {
+            javascript: '/(\\d)(?=(\\d{3})+(?!\\d))/g',
+            python: 'r"(\\d)(?=(\\d{3})+(?!\\d))"',
+            php: '/(\\d)(?=(\\d{3})+(?!\\d))/',
+            java: '(\\d)(?=(\\d{3})+(?!\\d))'
+        }
+    },
+    'phone-format': {
+        title: '手机号格式化',
+        description: '将手机号格式化为 xxx-xxxx-xxxx',
+        patterns: {
+            javascript: '/(\\d{3})(\\d{4})(\\d{4})/',
+            python: 'r"(\\d{3})(\\d{4})(\\d{4})"',
+            php: '/(\\d{3})(\\d{4})(\\d{4})/',
+            java: '(\\d{3})(\\d{4})(\\d{4})'
+        }
+    },
+    'date-format': {
+        title: '日期格式化',
+        description: '将日期字符串格式化为指定格式',
+        patterns: {
+            javascript: '/(\\d{4})-(\\d{2})-(\\d{2})/',
+            python: 'r"(\\d{4})-(\\d{2})-(\\d{2})"',
+            php: '/(\\d{4})-(\\d{2})-(\\d{2})/',
+            java: '(\\d{4})-(\\d{2})-(\\d{2})'
+        }
+    },
+    'card-format': {
+        title: '银行卡格式化',
+        description: '将银行卡号每4位添加一个空格',
+        patterns: {
+            javascript: '/(\\d{4})(?=\\d)/g',
+            python: 'r"(\\d{4})(?=\\d)"',
+            php: '/(\\d{4})(?=\\d)/',
+            java: '(\\d{4})(?=\\d)'
+        }
+    },
+    'idcard-format': {
+        title: '身份证格式化',
+        description: '将身份证号码按6-8-4格式分组',
+        patterns: {
+            javascript: '/(^\\d{6})(\\d{8})(\\d{4})/g',
+            python: 'r"(^\\d{6})(\\d{8})(\\d{4})"',
+            php: '/(^\\d{6})(\\d{8})(\\d{4})/',
+            java: '(^\\d{6})(\\d{8})(\\d{4})'
+        }
+    },
+
+    // 特殊字符类
+    'emoji': {
+        title: 'Emoji表情',
+        description: '匹配Unicode emoji表情符号',
+        patterns: {
+            javascript: '/[\\u{1F300}-\\u{1F9FF}]/gu',
+            python: 'r"[\\U0001F300-\\U0001F9FF]"',
+            php: '/[\\x{1F300}-\\x{1F9FF}]/u',
+            java: '[\\uD83C\\uDF00-\\uD83D\\uDDFF]'
+        }
+    },
+    'special-char': {
+        title: '特殊字符',
+        description: '匹配常见特殊字符',
+        patterns: {
+            javascript: '/[`~!@#$%^&*()_\\-+=<>?:"{}|,.\\/;\'\\[\\]·~!@#¥%……&*()——\\-+={}|《》?:""【】、;\',。、]/g',
+            python: 'r"[`~!@#$%^&*()_\\-+=<>?:\\"{}|,.\\/;\\\'\\[\\]·~!@#¥%……&*()——\\-+={}|《》?:""【】、;\\\',。、]"',
+            php: '/[`~!@#$%^&*()_\\-+=<>?:"{}|,.\\/;\'\\[\\]·~!@#¥%……&*()——\\-+={}|《》?:""【】、;\',。、]/',
+            java: '[`~!@#$%^&*()_\\-+=<>?:"{}|,.\\/;\'\\[\\]·~!@#¥%……&*()——\\-+={}|《》?:""【】、;\',。、]'
+        }
+    },
+    'invisible-char': {
+        title: '不可见字符',
+        description: '匹配不可见字符(空格、制表符、换行符等)',
+        patterns: {
+            javascript: '/[\\s\\u200B-\\u200D\\uFEFF]/g',
+            python: 'r"[\\s\\u200B-\\u200D\\uFEFF]"',
+            php: '/[\\s\\x{200B}-\\x{200D}\\x{FEFF}]/u',
+            java: '[\\s\\u200B-\\u200D\\uFEFF]'
+        }
+    },
+
+    // 编程相关
+    'variable': {
+        title: '变量命名',
+        description: '验证合法的变量名(字母、数字、下划线,字母开头)',
+        patterns: {
+            javascript: '/^[a-zA-Z_$][a-zA-Z0-9_$]*$/',
+            python: 'r"^[a-zA-Z_][a-zA-Z0-9_]*$"',
+            php: '/^[a-zA-Z_][a-zA-Z0-9_]*$/',
+            java: '^[a-zA-Z_$][a-zA-Z0-9_$]*$'
+        }
+    },
+    'function': {
+        title: '函数声明',
+        description: '匹配函数声明语句',
+        patterns: {
+            javascript: '/function\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\([^)]*\\)\\s*{/',
+            python: 'r"def\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\([^)]*\\)\\s*:"',
+            php: '/function\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\([^)]*\\)\\s*{/',
+            java: '(public|private|protected|static|\\s) +[\\w\\<\\>\\[\\]]+\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\([^)]*\\)\\s*\\{'
+        }
+    },
+    'json': {
+        title: 'JSON格式',
+        description: '验证JSON字符串格式',
+        patterns: {
+            javascript: '/^\\s*({[\\s\\S]*}|\\[[\\s\\S]*\\])\\s*$/',
+            python: 'r"^\\s*({[\\s\\S]*}|\\[[\\s\\S]*\\])\\s*$"',
+            php: '/^\\s*({[\\s\\S]*}|\\[[\\s\\S]*\\])\\s*$/',
+            java: '^\\s*({[\\s\\S]*}|\\[[\\s\\S]*\\])\\s*$'
+        }
+    },
+    'xml': {
+        title: 'XML标签',
+        description: '匹配XML标签',
+        patterns: {
+            javascript: '/<\\/?([a-z][\\w-]*)(?:\\s+[^>]*)?>/gi',
+            python: 'r"<\\/?([a-z][\\w-]*)(?:\\s+[^>]*)?>)"',
+            php: '/<\\/?([a-z][\\w-]*)(?:\\s+[^>]*)?>/i',
+            java: '<\\/?([a-z][\\w-]*)(?:\\s+[^>]*)?>'
+        }
+    },
+    'css': {
+        title: 'CSS选择器',
+        description: '匹配CSS选择器',
+        patterns: {
+            javascript: '/[.#]?[a-zA-Z_-][\\w-]*(?:\\[[^\\]]+\\])?(?:\\.[a-zA-Z_-][\\w-]*)*/',
+            python: 'r"[.#]?[a-zA-Z_-][\\w-]*(?:\\[[^\\]]+\\])?(?:\\.[a-zA-Z_-][\\w-]*)*"',
+            php: '/[.#]?[a-zA-Z_-][\\w-]*(?:\\[[^\\]]+\\])?(?:\\.[a-zA-Z_-][\\w-]*)*/',
+            java: '[.#]?[a-zA-Z_-][\\w-]*(?:\\[[^\\]]+\\])?(?:\\.[a-zA-Z_-][\\w-]*)*'
+        }
+    },
+
+    // 数字验证类
+    'number': {
+        title: '数字验证',
+        description: '验证是否为纯数字',
+        patterns: {
+            javascript: '/^\d+$/',
+            python: 'r"^\d+$"',
+            php: '/^\d+$/',
+            java: '^\\d+$'
+        }
+    },
+    'number-n-digits': {
+        title: 'n位数字验证',
+        description: '验证是否为n位数字(示例为4位)',
+        patterns: {
+            javascript: '/^\d{4}$/',
+            python: 'r"^\d{4}$"',
+            php: '/^\d{4}$/',
+            java: '^\\d{4}$'
+        }
+    },
+    'number-min-n-digits': {
+        title: '至少n位数字验证',
+        description: '验证是否至少包含n位数字(示例为6位)',
+        patterns: {
+            javascript: '/^\d{6,}$/',
+            python: 'r"^\d{6,}$"',
+            php: '/^\d{6,}$/',
+            java: '^\\d{6,}$'
+        }
+    },
+    'number-range-digits': {
+        title: '数字位数范围验证',
+        description: '验证数字位数是否在指定范围内(示例为6-18位)',
+        patterns: {
+            javascript: '/^\d{6,18}$/',
+            python: 'r"^\d{6,18}$"',
+            php: '/^\d{6,18}$/',
+            java: '^\\d{6,18}$'
+        }
+    },
+    'decimal': {
+        title: '小数验证',
+        description: '验证是否为小数',
+        patterns: {
+            javascript: '/^\d+\.\d+$/',
+            python: 'r"^\d+\.\d+$"',
+            php: '/^\d+\.\d+$/',
+            java: '^\\d+\\.\\d+$'
+        }
+    },
+    'integer': {
+        title: '整数验证',
+        description: '验证是否为整数(包括正负整数)',
+        patterns: {
+            javascript: '/^-?\\d+$/',
+            python: 'r"^-?\\d+$"',
+            php: '/^-?\\d+$/',
+            java: '^-?\\d+$'
+        }
+    },
+
+    // 文本格式类
+    'chinese-name': {
+        title: '中文姓名验证',
+        description: '验证中文姓名(2-6个汉字)',
+        patterns: {
+            javascript: '/^[\\u4e00-\\u9fa5]{2,6}$/',
+            python: 'r"^[\\u4e00-\\u9fa5]{2,6}$"',
+            php: '/^[\\x{4e00}-\\x{9fa5}]{2,6}$/u',
+            java: '^[\\u4e00-\\u9fa5]{2,6}$'
+        }
+    },
+    'english-name': {
+        title: '英文姓名验证',
+        description: '验证英文姓名(支持空格和点号)',
+        patterns: {
+            javascript: '/^[a-zA-Z][a-zA-Z\\s\\.]{0,58}[a-zA-Z]$/',
+            python: 'r"^[a-zA-Z][a-zA-Z\\s\\.]{0,58}[a-zA-Z]$"',
+            php: '/^[a-zA-Z][a-zA-Z\\s\\.]{0,58}[a-zA-Z]$/',
+            java: '^[a-zA-Z][a-zA-Z\\s\\.]{0,58}[a-zA-Z]$'
+        }
+    },
+    'username': {
+        title: '用户名验证',
+        description: '验证用户名(字母开头,允许5-16字节,允许字母数字下划线)',
+        patterns: {
+            javascript: '/^[a-zA-Z][a-zA-Z0-9_]{4,15}$/',
+            python: 'r"^[a-zA-Z][a-zA-Z0-9_]{4,15}$"',
+            php: '/^[a-zA-Z][a-zA-Z0-9_]{4,15}$/',
+            java: '^[a-zA-Z][a-zA-Z0-9_]{4,15}$'
+        }
+    },
+    'password-strong': {
+        title: '强密码验证',
+        description: '验证密码强度(必须包含大小写字母和数字,可以包含特殊字符,长度8-16)',
+        patterns: {
+            javascript: '/^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9!@#$%^&*]{8,16}$/',
+            python: 'r"^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9!@#$%^&*]{8,16}$"',
+            php: '/^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9!@#$%^&*]{8,16}$/',
+            java: '^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9!@#$%^&*]{8,16}$'
+        }
+    },
+
+    // 特殊格式类
+    'mac-address': {
+        title: 'MAC地址验证',
+        description: '验证MAC地址格式',
+        patterns: {
+            javascript: '/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/',
+            python: 'r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"',
+            php: '/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/',
+            java: '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'
+        }
+    },
+    'hex-color': {
+        title: '16进制颜色验证',
+        description: '验证16进制颜色代码',
+        patterns: {
+            javascript: '/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/',
+            python: 'r"^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$"',
+            php: '/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/',
+            java: '^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$'
+        }
+    },
+    'version-number': {
+        title: '版本号验证',
+        description: '验证版本号格式(x.y.z)',
+        patterns: {
+            javascript: '/^\\d+\\.\\d+\\.\\d+$/',
+            python: 'r"^\\d+\\.\\d+\\.\\d+$"',
+            php: '/^\\d+\\.\\d+\\.\\d+$/',
+            java: '^\\d+\\.\\d+\\.\\d+$'
+        }
     }
-});
+};
 
-var RegExpTools = (function () {
-
-    "use strict";
-
-    var regElm, srcElm, rstElm, rstCount, srcBackgroundElm, srcWrapperElm, regListElm;
-    var ID_PREFIX = 'tmp_id_';
-    var TAG_MATCHED = 'b';
-    var TAG_NOT_MATCHED = 'i';
-    var TR_ID_PREFIX = 'tr_' + ID_PREFIX;
-
-    var _getRegExp = function (regTxt) {
-        try {
-            return new Function('return ' + regTxt)();
-        } catch (e) {
-            return null;
-        }
-    };
-
-    var _buildTable = function (rstArray) {
-        var tbl = ["<table class='table table-bordered table-striped table-condensed table-hover'>"];
-        tbl.push('<tr class="active"><th class="num">序号</th><th>匹配结果</th><th>在原字符串中的位置</th></tr>')
-        $.each(rstArray, function (i, item) {
-            tbl.push('<tr id="' + TR_ID_PREFIX + item.index + '" data-index="' + item.index + '">');
-            tbl.push('<td class="num">' + (i + 1) + '</td>'
-                + '<td class="content">' + item.text + '</td>'
-                + '<td class="index">' + item.index + '</td>');
-            tbl.push('</tr>');
-        });
-        tbl.push('</table>');
-        return tbl.join('');
-    };
-
-    var _createTag = function (type, item) {
-        var tags = [];
-        for (var i = 0, len = item.text.length; i < len; i++) {
-            tags.push('<' + type + ' data-id="' + ID_PREFIX + item.index + '">'
-                + item.text.charAt(i) + '</' + type + '>');
-        }
-        return tags.join('');
-    };
-
-    var _blinkHighlight = function () {
-        $('tr[id^=' + TR_ID_PREFIX + ']').click(function (e) {
-            var index = $(this).attr('data-index');
-            var tags = $(TAG_MATCHED + '[data-id=' + ID_PREFIX + index + ']');
-            tags.animate({
-                opacity:0
-            }, 200).delay().animate({
-                    opacity:1
-                }, 200).delay().animate({
-                    opacity:0
-                }, 200).delay().animate({
-                    opacity:1
-                }, 200);
-        });
-    };
-
-    var _highlight = function (srcText, rstArray) {
-        if (!srcText) {
-            srcBackgroundElm.html('');
-            return;
-        }
-        var hl = [];
-        var preIndex = 0;
-        $.each(rstArray, function (i, item) {
-            if (i === 0) {
-                if (item.index === 0) {
-                    hl.push(_createTag(TAG_MATCHED, item));
-                } else {
-                    hl.push(_createTag(TAG_NOT_MATCHED, {
-                        index:0,
-                        text:srcText.substring(0, item.index)
-                    }));
-                    hl.push(_createTag(TAG_MATCHED, item));
-                }
-            } else {
-                preIndex = rstArray[i - 1].index + rstArray[i - 1].text.length;
-                hl.push(_createTag(TAG_NOT_MATCHED, {
-                    index:preIndex,
-                    text:srcText.substring(preIndex, item.index)
-                }));
-                hl.push(_createTag(TAG_MATCHED, item));
+// 初始化事件监听
+document.addEventListener('DOMContentLoaded', () => {
+    const modal = document.getElementById('regexModal');
+    const closeBtn = document.querySelector('.close');
+    const regexItems = document.querySelectorAll('.regex-item');
+    const copyButtons = document.querySelectorAll('.copy-btn');
+
+    // 点击正则表达式项显示模态框
+    regexItems.forEach(item => {
+        item.addEventListener('click', () => {
+            const regexId = item.getAttribute('data-regex-id');
+            const regexData = regexDatabase[regexId];
+            
+            if (regexData) {
+                document.getElementById('modalTitle').textContent = regexData.title;
+                document.getElementById('jsRegex').textContent = regexData.patterns.javascript;
+                document.getElementById('pythonRegex').textContent = regexData.patterns.python;
+                document.getElementById('phpRegex').textContent = regexData.patterns.php;
+                document.getElementById('javaRegex').textContent = regexData.patterns.java;
+                document.getElementById('regexDescription').textContent = regexData.description;
+                
+                modal.style.display = 'block';
             }
         });
-        srcBackgroundElm.html(hl.join(''));
-        _blinkHighlight();
-    };
-
-    var _emptyTable = function (message) {
-        var tbl = ["<table class='table table-bordered table-striped table-condensed table-hover'>"];
-        tbl.push('<tr class="active"><th class="num">序号</th><th>匹配结果</th></tr>');
-        tbl.push('<tr><td colspan="2">' + message + '</td></tr>');
-        tbl.push('</table>');
-        return tbl.join('');
-    };
-
-    var _dealRegMatch = function (e) {
-        srcWrapperElm.height(srcElm.height() + 24);
-
-        var regTxt = regElm.val().trim();
-        var srcTxt = srcElm.val().trim();
-        if (!regTxt || !srcTxt) {
-            rstElm.html(_emptyTable('不能匹配'));
-            rstCount.html('0个');
-            _highlight();
-        } else {
-            var reg = _getRegExp(regTxt);
-            if (!reg || !reg instanceof RegExp) {
-                rstElm.html(_emptyTable('正则表达式错误!'));
-                rstCount.html('0个');
-                _highlight();
-                return;
-            }
-            var rst = [];
-            // 用字符串的replace方法来找到匹配目标在元字符串中的准确位置
-            srcTxt.replace(reg, function () {
-                var matchedTxt = arguments[0];
-                var txtIndex = arguments[arguments.length - 2];
-                rst.push({
-                    text:matchedTxt,
-                    index:txtIndex
-                });
-            });
-            if (!rst || !rst.length) {
-                rstElm.html(_emptyTable('不能匹配'));
-                rstCount.html('0个');
-                _highlight();
-            } else {
-                rstElm.html(_buildTable(rst));
-                rstCount.html(rst.length + '个');
-                _highlight(srcElm.val(), rst);
-            }
+    });
+
+    // 关闭模态框
+    closeBtn.addEventListener('click', () => {
+        modal.style.display = 'none';
+    });
+
+    // 点击模态框外部关闭
+    window.addEventListener('click', (event) => {
+        if (event.target === modal) {
+            modal.style.display = 'none';
         }
-    };
-
-    var _init = function () {
-        regElm = $('#regText');
-        srcElm = $('#srcCode');
-        srcBackgroundElm = $('#srcBackground');
-        srcWrapperElm = $('#srcWrapper');
-        rstElm = $('#rstCode').html(_emptyTable('暂无输入'));
-        rstCount = $('#rstCount');
-        regListElm = $('#regList');
-
-        // 输入框自适应高度
-        regElm.textareaAutoHeight({minHeight:34});
-        srcElm.textareaAutoHeight({minHeight:50});
-        srcBackgroundElm.textareaAutoHeight({minHeight:50});
-
-        // 监听两个输入框的按键、paste、change事件
-        $('#regText,#srcCode').keyup(_dealRegMatch).change(_dealRegMatch)
-            .bind('paste', _dealRegMatch);
-
-        regListElm.change(function (e) {
-            var reg = $(this).val();
-            var regTipElm = $('#regTip');
-            regElm.val(reg);
-            if (!reg) {
-                regTipElm.hide();
-            } else {
-                regTipElm.show();
-            }
+    });
+
+    // 复制按钮功能
+    copyButtons.forEach(button => {
+        button.addEventListener('click', () => {
+            const targetId = button.getAttribute('data-target');
+            const codeElement = document.getElementById(targetId);
+            const text = codeElement.textContent;
+
+            navigator.clipboard.writeText(text).then(() => {
+                const originalText = button.textContent;
+                button.textContent = '已复制!';
+                button.style.backgroundColor = '#27ae60';
+                
+                setTimeout(() => {
+                    button.textContent = originalText;
+                    button.style.backgroundColor = '#3498db';
+                }, 2000);
+            }).catch(err => {
+                console.error('复制失败:', err);
+                button.textContent = '复制失败';
+                button.style.backgroundColor = '#e74c3c';
+                
+                setTimeout(() => {
+                    button.textContent = '复制';
+                    button.style.backgroundColor = '#3498db';
+                }, 2000);
+            });
         });
-    };
+    });
+});
+
+// 搜索功能实现
+document.addEventListener('DOMContentLoaded', function() {
+    const searchInput = document.getElementById('regexSearch');
+    const regexItems = document.querySelectorAll('.regex-item');
 
-    return {
-        init:_init
-    };
-})();
+    searchInput.addEventListener('input', function(e) {
+        const searchTerm = e.target.value.toLowerCase().trim();
+        
+        regexItems.forEach(item => {
+            const text = item.textContent.toLowerCase();
+            const match = text.includes(searchTerm);
+            
+            item.classList.toggle('hidden', !match);
+            item.classList.toggle('highlight', match && searchTerm !== '');
+            
+            // 处理分类标题的显示/隐藏
+            const category = item.closest('.category');
+            const visibleItems = category.querySelectorAll('.regex-item:not(.hidden)');
+            category.style.display = visibleItems.length > 0 ? 'block' : 'none';
+        });
+    });
 
-RegExpTools.init();
+    // 添加清空搜索框的快捷键(ESC)
+    searchInput.addEventListener('keydown', function(e) {
+        if (e.key === 'Escape') {
+            searchInput.value = '';
+            // 触发 input 事件以更新显示
+            searchInput.dispatchEvent(new Event('input'));
+        }
+    });
+});