正如您自己注意到的那样,通常这必须使用某种解析器来完成。使用正则表达式只是很痛苦,并且那里有很多解析器/语法模块。
我创建了一个一次性解决方案脚本(在 nodejs 中),它使用正则表达式和缩进数来匹配开始到结束if / else
语句。如果满足以下条件,它将起作用:
- 文件格式正确,开头
if
的缩进数与结尾的缩进数相同else
这有效:
if(a) {
if(b) {
} else { // i have same amount of indents as my matching if, works!
}
}
这不起作用:
if(a) {
if(b) {
} else { // i have to many indents.
}
}
- 不能有
if
和else
在同一条线上!(通常不应该..)
这是我想出的脚本,它存储所有行号,if
其中没有else
. 您可以检查行号并单击给定的if
,然后 vs 代码突出显示结束括号,您可以添加else
. 它使用 lodash 但最终仅用于展平结果。这不是真正的依赖..
import { EOL } from 'os'
import * as fs from 'fs'
import { flatten } from 'lodash'
// Import your code file:
const code = fs.readFileSync('code.js').toString()
// Regex for matching lines holding if's..
// if(...)
// if() {
// if
const match_if = /if\s?\([^)]+\)\s+?/
// Regex for matching lines holding else:
// }else
// } else
// else {
// }else{
// ...
const match_else = /(\n|})\s?else({|\s|$)/
// small helper fpr calculating indents for first character appearing..
const calculate_indent = (line: string) => {
let spaces = 0
while(line.charAt(spaces) === ' ') {
spaces++
}
return spaces
}
// split up the lines by system operator
const lines = code.split(EOL)
const indexes = []
// iterate all lines.
for(let i =0; i < lines.length; i++) {
const line = lines[i]
// do not process empty lines..
if(!line || line.trim().length < 2) {
continue
}
// Match the line against if regex
const if_match = line.match(match_if)
// process the match if there is an if found!
if(if_match && if_match.length > 0) {
// Count the indents, we need this latere
// to match any found "else" to the correct if.
// make sure your code is properly formatted and indent levels are correct!!
const level = calculate_indent(line)
// Make sure under given level is an array
if(Array.isArray(indexes[level]) === false) {
indexes[level] = []
}
// store line number to the given level.
// For a human the line number is index + 1
indexes[level].push(i+1)
}
// We check the line for else. Note:
// The whole function won't work for any if() else combinations on the same line..
const else_match = line.match(match_else)
if(else_match && else_match.length > 0) {
// count index to identify level for matching the correct if.
const level = calculate_indent(line)
if(Array.isArray(indexes[level])) {
// remove the last stored if. We know it ended here!
indexes[level].splice(indexes[level].length-1, 1)
}
}
}
console.log('lines:', lines.length)
console.log('results:', indexes)
// flatten / remove empty items / sort
const line_numbers = flatten(indexes).filter(d => !!d).sort((a,b) => a-b)
console.log('final lines:', line_numbers)
我用这段代码测试了它:
if(sdf) {
if(sdf) {
}
}
if(asdf) {
if(sdfsdf) {
if(sdfsdf) {
} else {
}
} else {
}
} else {
}
if(asdf) {
if(sdfsdf) {
} else {
if(sdf) {
}
if(sdf) {
} else {
}
if(sdf) {
}
}
}
结果 =>final lines: [ 2, 4, 29, 34, 45 ]
您可能想在使用前多测试一下!但是当缩进正确时它应该可以工作。这篇文章也是相关的,很好读!=>为什么你不应该使用正则表达式来解析树结构......