如何在AvalonEdit的XSHD中用正则区分*的乘号与注释符?
嘿,我正好在AvalonEdit里做过类似的语法高亮需求,你的问题核心是要区分作为乘号的*和作为注释起始的*,之前的两种Span方案都没考虑上下文逻辑,所以才会出现错误匹配的情况。给你一个基于状态机+正则环视的解决方案,完美适配你的三个测试场景:
最终XSHD配置
<SyntaxDefinition name="EquationWithComments" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> <!-- 定义颜色方案,你可以根据自己的需求修改 --> <Color name="Comment" foreground="#FF008000" /> <Color name="MultiplicationOperator" foreground="#FF800080" /> <Color name="Variable" foreground="#FF0000FF" /> <Color name="EqualsSign" foreground="#FFFF0000" /> <!-- 默认状态:处理不带等号的行,或者等号左侧的内容 --> <RuleSet name="Default"> <!-- 匹配变量名 --> <Rule color="Variable">\b[a-zA-Z0-9_]+\b</Rule> <!-- 匹配等号,遇到等号后切换到等式右侧状态 --> <Rule color="EqualsSign">=</Rule> <Span begin="=" end="$" ruleSet="EquationRight" /> <!-- 默认状态下所有*都是注释起始 --> <Span color="Comment" begin="\*" end="\n" /> </RuleSet> <!-- 等式右侧状态:处理等号后的表达式,区分乘号和注释 --> <RuleSet name="EquationRight"> <!-- 优先匹配乘号:仅当*前后是完整变量/数字时,标记为乘号 --> <Rule color="MultiplicationOperator">(?<=\b[a-zA-Z0-9_]+\b)\s*\*(?=\s*\b[a-zA-Z0-9_]+\b)</Rule> <!-- 匹配等式右侧的变量 --> <Rule color="Variable">\b[a-zA-Z0-9_]+\b</Rule> <!-- 未被识别为乘号的*,一律作为注释起始,标记后切回默认状态 --> <Span color="Comment" begin="\*" end="\n" ruleSet="Default" /> </RuleSet> </SyntaxDefinition>
方案逻辑说明
- 状态切换:通过
RuleSet实现状态流转,遇到=就进入EquationRight状态,专门处理等式右侧的表达式;其他情况留在Default状态。 - 乘号优先匹配:在等式右侧状态里,用正则环视
(?<=\b[a-zA-Z0-9_]+\b)\s*\*(?=\s*\b[a-zA-Z0-9_]+\b)精准匹配作为乘法运算符的*——只有当*前后都是完整的变量/数字(可带空格)时,才会被标记为乘号。 - 注释兜底:所有未被识别为乘号的
*,都会被作为注释起始,从*到行尾的内容都会被高亮为注释。
测试你的三个例子
- 例子1:
a = b * c:*前后是b和c,被识别为乘号,c正常标记为变量,无错误注释高亮。 - 例子2:
abcdef abcd * a comment:处于默认状态,*直接触发注释高亮,后面的所有内容都被标记为注释。 - 例子3:
a = b * c * a comment:第一个*被识别为乘号,第二个*未满足乘号的匹配规则,触发注释高亮,后面的a comment被标记为注释。
为什么之前的方案行不通?
- 第一个方案
<Span color="Comment" begin="\*" end="\n" />完全不区分上下文,把所有*都当成注释起始,自然会把乘号后面的内容误判为注释。 - 第二个方案的负前瞻正则逻辑错误,它试图匹配“行内没有
=后跟*”的情况,反而会把带等式的行错误地整体标记为注释,完全不符合需求。
AvalonEdit 5.0.4完全支持状态机和正则环视语法,这个方案可以直接用哦!
内容的提问来源于stack exchange,提问作者NirMH
相关产品推荐
相关产品推荐

