196 lines
5.4 KiB
Vue
196 lines
5.4 KiB
Vue
<template>
|
|
<div class="regexp-tester">
|
|
<h1>正则表达式测试器</h1>
|
|
<el-input v-model="regex" placeholder="请输入正则表达式" clearable class="regex-input" />
|
|
<el-input v-model="testString" placeholder="请输入测试字符串" clearable class="test-input" />
|
|
<el-button type="primary" @click="testRegex" class="test-button">测试</el-button>
|
|
<el-button type="default" @click="saveRegex" class="test-button" :disabled="shouldDisableSaveButton">保存</el-button>
|
|
<!-- 添加匹配示意图 -->
|
|
<div class="match-diagram">
|
|
<h2>匹配示意图</h2>
|
|
<div class="diagram-content" ref="myDiagram">
|
|
<!-- <pre v-html="generateMatchDiagram()"></pre> -->
|
|
</div>
|
|
</div>
|
|
<div class="results">
|
|
<h2>匹配结果</h2>
|
|
<div v-if="results.length === 0" class="result-item">
|
|
<p>未找到匹配项</p>
|
|
</div>
|
|
<div v-for="(result, index) in results" :key="index" class="result-item">
|
|
<p>匹配内容: {{ result.match }}</p>
|
|
<p>匹配位置: {{ result.index }}</p>
|
|
<div v-if="result.groups && result.groups.length > 0">
|
|
<p>捕获组:</p>
|
|
<ul>
|
|
<li v-for="(group, groupIndex) in result.groups" :key="groupIndex">
|
|
组 {{ groupIndex + 1 }}: {{ group }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<el-dialog v-model="dialogVisible" :modal="false">
|
|
<el-input placeholder="保存为" v-model="regxname" />
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="saveRegex">保存</el-button>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted,computed } from 'vue'
|
|
import { ElInput, ElButton } from 'element-plus'
|
|
// 在你的组件文件中
|
|
let vscode: any = null
|
|
// 现在你可以在这个文件中使用 window.vizregx 而不会得到 TypeScript 的错误
|
|
const regex = ref('')
|
|
const testString = ref('')
|
|
const dialogVisible = ref(false)
|
|
const regxname = ref('')
|
|
const results = ref<{ match: string; index: number; groups: string[] }[]>([])
|
|
const myDiagram = ref<HTMLElement | null>(null)
|
|
const testRegex = () => {
|
|
try {
|
|
// 确保正则表达式带有全局标志 'g'
|
|
const regexPattern = new RegExp(regex.value, 'g')
|
|
const matches = testString.value.matchAll(regexPattern)
|
|
results.value = Array.from(matches, (match) => ({
|
|
match: match[0],
|
|
index: match.index || 0,
|
|
groups: match.slice(1), // 捕获组结果
|
|
}))
|
|
if (myDiagram.value && typeof window.vizregx !== 'undefined') {
|
|
//先删除之前的匹配示意图
|
|
myDiagram.value.innerHTML = ''
|
|
window.vizregx(myDiagram.value, regex.value)
|
|
}
|
|
} catch (error) {
|
|
console.error('Invalid regex:', error)
|
|
results.value = []
|
|
}
|
|
}
|
|
const isInVscode = () => {
|
|
return typeof window.acquireVsCodeApi !== 'undefined'
|
|
}
|
|
const shouldDisableSaveButton = computed(() => {
|
|
return !regex.value || !testString.value
|
|
})
|
|
const saveRegex = () => {
|
|
// show a dialog to ask for a name
|
|
if (!dialogVisible.value) {
|
|
dialogVisible.value = true
|
|
} else {
|
|
dialogVisible.value = false
|
|
if (isInVscode()) {
|
|
if(!vscode) vscode = window.acquireVsCodeApi()
|
|
vscode.postMessage({ command: 'regex.save', name:regxname.value, regexp: regex.value, teststr: testString.value })
|
|
}
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
// 此时 myDiagram.value 应该已经被设置为对应的 DOM
|
|
if (isInVscode()) {
|
|
window.addEventListener('message', (event) => {
|
|
const message = event.data
|
|
if (message.command === 'regex.show') {
|
|
regex.value = message.regexp
|
|
|
|
testString.value = message.teststr
|
|
testRegex()
|
|
}
|
|
})
|
|
}
|
|
})
|
|
// // 生成匹配示意图
|
|
// const generateMatchDiagram = () => {
|
|
// let diagram = testString.value
|
|
// results.value.forEach((result) => {
|
|
// const start = result.index
|
|
// const end = start + result.match.length
|
|
// diagram =
|
|
// diagram.slice(0, start) +
|
|
// `<span class="highlight">${diagram.slice(start, end)}</span>` +
|
|
// diagram.slice(end)
|
|
// })
|
|
// return diagram
|
|
// }
|
|
</script>
|
|
|
|
<style scoped>
|
|
.regexp-tester {
|
|
padding: 20px;
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
/* background-color: #1e1e1e; /* 暗色背景 */
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
h1,
|
|
h2 {
|
|
text-align: center;
|
|
/* color: #ffffff; /* 白色文字 */
|
|
}
|
|
|
|
.regex-input,
|
|
.test-input {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.test-button {
|
|
width: 100%;
|
|
margin-bottom: 15px;
|
|
margin-left: 0px;
|
|
}
|
|
|
|
.results {
|
|
margin-top: 20px;
|
|
padding: 15px;
|
|
/* background-color: #2d2d2d; /* 暗色背景 */
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.result-item {
|
|
/* border: 1px solid #444444; /* 暗色边框 */
|
|
padding: 10px;
|
|
margin-bottom: 10px;
|
|
border-radius: 4px;
|
|
/* background-color: #333333; /* 暗色背景 */
|
|
}
|
|
|
|
.result-item p {
|
|
margin: 5px 0;
|
|
/*color: #cccccc; /* 浅灰色文字 */
|
|
}
|
|
|
|
/* 匹配示意图样式 */
|
|
.match-diagram {
|
|
margin-top: 20px;
|
|
padding: 15px;
|
|
/*background-color: #2d2d2d; /* 暗色背景 */
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.diagram-content {
|
|
padding: 10px;
|
|
/*background-color: #333333; /* 暗色背景 */
|
|
/* border: 1px solid #444444; /* 暗色边框 */
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.diagram-content pre {
|
|
margin: 0;
|
|
/* color: #cccccc; /* 浅灰色文字 */
|
|
}
|
|
|
|
.highlight {
|
|
/* background-color: #ffeb3b; /* 高亮颜色 */
|
|
padding: 2px 4px;
|
|
border-radius: 3px;
|
|
}
|
|
</style>
|