如何在没有 else 的情况下找到所有 if 语句?
How can I find all if-statements without an else?
我有很多代码,其中有时写了 if 语句,但没有匹配的 else 语句。在某些地方,这是一个问题,因为当出现故障时,故障没有得到正确处理。我想手动确认所有发生 if-without-an-else 的地方。
我试过使用正则表达式,但我没有成功找到匹配右括号的方法,因为正则表达式 cannot really handle nested brackets.
我要查找的代码如下所示:
if( ... ) {
...
}
我不想找到的代码,看起来像这样:
if( ... ) {
...
}
else {
...
}
如何列出所有这些地点,以便我浏览它们?
正如您自己注意到的,通常这必须使用某种解析器来完成。使用正则表达式简直就是痛苦,那里有很多解析器/语法模块。
我创建了一个一次性解决方案脚本(在 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 ]
在使用它之前,您可能想多测试一下!
但是当缩进正确时它应该可以工作。这篇文章也是相关的,很高兴阅读! => why you should not use regex to parse tree structures....
我有很多代码,其中有时写了 if 语句,但没有匹配的 else 语句。在某些地方,这是一个问题,因为当出现故障时,故障没有得到正确处理。我想手动确认所有发生 if-without-an-else 的地方。
我试过使用正则表达式,但我没有成功找到匹配右括号的方法,因为正则表达式 cannot really handle nested brackets.
我要查找的代码如下所示:
if( ... ) {
...
}
我不想找到的代码,看起来像这样:
if( ... ) {
...
}
else {
...
}
如何列出所有这些地点,以便我浏览它们?
正如您自己注意到的,通常这必须使用某种解析器来完成。使用正则表达式简直就是痛苦,那里有很多解析器/语法模块。
我创建了一个一次性解决方案脚本(在 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 ]
在使用它之前,您可能想多测试一下!
但是当缩进正确时它应该可以工作。这篇文章也是相关的,很高兴阅读! => why you should not use regex to parse tree structures....