JavaScript如何编写正则校验含非嵌套括号的大写字母逻辑公式
JavaScript 逻辑表达式输入正则校验方案
明确校验规则
- 合法字符范围:仅允许A-Z大写英文字母、逻辑连接词
and/or、英文半角括号()、单词间半角空格 - 括号规则:禁止嵌套,左右括号数量必须完全匹配
- 邻接规则:
- 左括号
(后仅允许接A-Z大写字母 - 右括号
)后仅允许接逻辑连接词and/or或直接到字符串末尾 - 禁止连续出现逻辑连接词、禁止无连接词直接相邻的运算单元、禁止首尾悬空连接词
- 左括号
测试用例参考
合法输入
A and B and C and D (A or B) and C (A or B or C) and D (A or B or C or D) and E A and (B or C) and D A and (B or C) or (C and D) A or (B and C) (A and B) or (C and D)
非法输入
A and B and C and (A or B and C (A or B or C) and D or (A or B or C or D and E A and or (B or C) and D A and (B or (C and D))) A (B and C) (A and B) or C and D) (A and B or C and D)
现有正则问题
你当前使用的正则/^[A-Z(]?[A-Z]| |and|or|[(]|[A-Z]|[)]/gm存在核心逻辑缺陷:
- 未做整串匹配锚定,只会匹配字符串中的合法片段,无法识别片段外的非法内容
- 未实现括号匹配、邻接字符校验、连接词连续性校验的逻辑
- 全局匹配模式会把包含非法片段的字符串误判为合法
最终可用正则
以下正则可完全覆盖列明的所有核心校验规则:
/^(?:[A-Z]|\([A-Z](?: (?:and|or) [A-Z])*\))(?: (?:and|or) (?:[A-Z]|\([A-Z](?: (?:and|or) [A-Z])*\)))*$/
逻辑拆解
- 首尾用
^和$锚定,强制整串完全匹配,避免漏判非法片段 - 先定义两类合法运算单元:
- 单个大写字母
[A-Z] - 括号包裹的非嵌套表达式:
\([A-Z](?: (?:and|or) [A-Z])*\),从结构上直接禁止括号嵌套,同时保证左括号后必须是大写字母
- 单个大写字母
- 整体表达式结构固定为「单个运算单元 + N组(连接词+运算单元)」,从结构上禁止连续连接词、无连接词相邻单元、首尾悬空连接词的问题,同时保证右括号后只能接连接词或字符串末尾
使用示例
const logicReg = /^(?:[A-Z]|\([A-Z](?: (?:and|or) [A-Z])*\))(?: (?:and|or) (?:[A-Z]|\([A-Z](?: (?:and|or) [A-Z])*\)))*$/; // 合法用例校验 const validList = [ "A and B and C and D", "(A or B) and C", "(A or B or C) and D", "(A or B or C or D) and E", "A and (B or C) and D", "A and (B or C) or (C and D)", "A or (B and C)", "(A and B) or (C and D)" ]; console.log(validList.every(item => logicReg.test(item))); // 输出true // 非法用例校验 const invalidList = [ "A and B and C and ", "(A or B and C", "(A or B or C) and D or", "(A or B or C or D and E", "A and or (B or C) and D", "A and (B or (C and D)))", "A (B and C)", "(A and B) or C and D)", "(A and B or C and D)" ]; console.log(invalidList.every(item => !logicReg.test(item))); // 输出true
如果需要兼容多空格场景,可以将正则中的单个空格替换为
\s+,同时校验前先对输入做trim()处理去除首尾空格。
内容的提问来源于stack exchange,提问作者psychozub
相关产品推荐
相关产品推荐

