parsing - 捕获包含 - 但不以破折号结尾的名称
问题描述
我正在尝试捕获可能包含破折号的名称(不以数字开头),例如hello-world
. 我的问题是我也有与它冲突的单个破折号和符号的规则:
[A-Za-z][A-Za-z0-9-]+ { /* capture "hello-world" */ }
"-" { return '-'; }
">" { return '>'; }
当词法分析器读取hello-world->
前面的规则时,会产生hello-world-
and >
,而我期望hello-world
,-
和>
被单独捕获。为了解决它,我以这种方式修复了它:
[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+ { /* ensure final dash is never included at the end */ }
这行得通,除了单字母单词,所以最后我实现了这个:
[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+ { /* ensure final dash is never included at the end */ }
[A-Za-z][A-Za-z0-9]* { /* capture possible single letter words */ }
问题:有没有更优雅的方法来做到这一点?
解决方案
[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+ [A-Za-z][A-Za-z0-9]*
请注意,正如您所说,第一条规则已经涵盖了不是单个字母的所有内容。所以第二条规则只需要匹配单个字母并且可以缩短为[A-Za-z]
:
[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]+
[A-Za-z]
现在第二个规则只是第一个规则的前缀,所以我们可以通过使第一个字母后面的部分成为可选的部分来将其组合成一个规则:
[A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9]+)?
最后+
一位是不必要的,因为除了最后一个字符之外的所有内容都可以与中间部分匹配,所以最简单的版本是:
[A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9])?
推荐阅读
- visual-studio - Visual Studio docker 支持不适用于 CI/CD
- tableau-api - Tableau 混合聚合和非聚合 IF
- xml - 使用 LF 和 UTF-8 在 powershell 中创建 XML 失败
- java - 如何在方法中测试 atomicboolean
- delphi - HTTPRIO ContentType application/soap+xml 的 Delphi SOAP 请求
- angular - 如何读取在 iframe 中打开的网站的网址
- c - 如何检查我从 .c 文件中读取的行是否包含 #include
? - r - 获取按 R 中学校分组的学生的每个项目的信息
- botframework - Bot Framework - 企业模板 .bot 文件丢失
- xml - 无法使用 Import-Clixml 或 Get-Content 读取/导入 Windows XML 日志文件