regex - 正则表达式:确认可选部分是否匹配
问题描述
我有一个可以有两种形式的字符串,不知道每次都是哪种形式:
hello world[0:10];
或者hello world;
可能有也可能没有带数字的括号。这两个词(你好和世界)可能会有所不同。如果有括号和数字,则第一个数字始终为 0,而第二个数字 (10) 会有所不同。
我需要捕获第一个单词 (hello),如果存在,则捕获第二个数字 (10)。我还需要知道它是哪种形式的字符串。
hello world[0:10];
我会捕获 {hello, 10, form1},hello world;
我会捕获 {hello, form2}。我并不关心“表单”的格式,我只需要能够区分。它可能有点(1=form1, 0=form2),结构(form1 将我置于一个范围,而 form2 将我置于另一个范围)等。
我目前有以下(现在正在工作)正则表达式:
/(\w*) \s \w* (?:\[0:(\d*)\])?;/x
这给了我$1 = hello
和潜在$2 = 10
的。我现在只需要知道括号中的数字是否存在。这将重复很多次,所以我不能假设$2 = undef
进入正则表达式。$2
也可能连续几次是同一件事,所以我不能只$2
在正则表达式之前和之后寻找变化。
到目前为止,我最好的解决方案是运行正则表达式两次,第一次使用括号,第二次没有:
if( /(\w*) \s \w* \[0:(\d*)\];/x ) {...}
elsif( /(\w*) \s \w*;/x ) {...}
这似乎非常低效和不优雅,所以我想知道是否有更好的方法?
解决方案
您可以使用?
选择性地匹配您的正则表达式的部分。然后,您可以直接将输出捕获为正则表达式的返回值。
my $re = qr{ (\w*) \s* (?:\[0:(\d+)\])?; }x;
if( my($word, $num) = $line =~ $re ) {
say "Word: $word";
say "Num: $num" if defined $num;
}
else {
say "No match";
}
(?:\[0:(\d+)\])?
说可能有[0:\d+]
。(?:)
使分组不被捕获,因此仅\d+
被捕获。
$1
并且$2
使用起来也很安全,它们在每次匹配时都会重置,但是使用词法变量会使事情更加明确。
推荐阅读
- mongodb - 无法在 localhost:3001 连接到 MongoDB
- idris - 如何在向量长度上说服 Idris
- angular - 如何在表单控件中设置默认布尔值 false
- python - Scrapy 无法到达 start_urls:DEBUG: Crawled (200) and ERROR
- here-api - 直接路由
- javafx - 如何在 install4J 中将 javafx 与 JRE 14 捆绑在一起?
- java - 这段代码会以另一种方式是什么
- python - 熊猫按其他列的数量填充列
- typo3 - 如何从一个模块中打开web_layout模块并返回
- ruby - 检查 Ruby 中的有效输入