我有一个带有模式的文本文件,如下所示。
“S | O | M |百灵| N | K | V | A |升| U | E | S | CAP1 {捕获|这些|值} | S | O | M |百灵| N | K | V | A |升| U | E | S | CAP2 [捕获|这些|值] | S | O | M |百灵| N | K | v | A |升| U | E | S | CAP3 {[捕获|这些|值] | [捕获|这些|值]}“
我正在尝试提取值 cap1 , cap2 , CAP3 。
我正在尝试使用正则表达式"([a-z]|[|])cap1(\{(.*?)\})([a-z]|[|]|[0-9])"
,但没有运气,任何帮助都会受到赞赏。
答案 0 :(得分:1)
据我所知,你想逐一提取cap1,cap2,CAP3的值。那么有3个正则表达式
cap1
cap1\{([^\}]*)\}
<强>解释强>
cap1\{
匹配文字cap1{
,
([^\}]*)
将}
以外的任何字符捕获到组$1
,
\}
匹配文字}
。
cap2
cap2\[([^\]]*)\]
<强>解释强>
cap2\[
匹配文字cap2[
,
([^\]]*)
将]
以外的任何字符捕获到组$1
,
\]
匹配文字]
。
CAP3
CAP3\{\[([^\]]*)\]\|\[([^\]]*)\]\}
<强>解释强>
CAP3\{
匹配文字CAP3{
,
\[([^\]]*)\]\|\[([^\]]*)\]
将]
以外的任何字符分别捕获到群组$1
,$2
,
\}
匹配文字}
。
补充:感谢@Borodin发表评论,要完成此任务,您不需要使用环视,但如果您想进行搜索和替换,可能需要环视
cap1
:(?<=cap1\{)([^\}]*)(?=\})
cap2
:(?<=cap2\[)([^\]]*)(?=\])
CAP3
:(?<=CAP3\{)\[([^\]]*)\]\|\[([^\]]*)\](?=\})
答案 1 :(得分:0)
使用这样的模式应该有效:
[{\[]+([^}{\]\[]+)[\]}]+
<强>代码强>:
$searchText =~ m/[{\[]+([^}{\]\[]+)[\]}]+/
示例强>:
答案 2 :(得分:0)
我道歉 - 我最初将你的问题误认为是一件更为琐碎的事情
基本上,您希望对管道split
字符执行|
,不包括括号或大括号[ ... ]
或{ ... }
对中的字符。只要你不需要考虑相同类型的括号内的嵌套(即括号只包含括号,括号只会包含括号),那么它就像这样完成
my @matches = $s =~ m{ \w+ ( \{ [^{}]* \} | \[ [^\[\]]* \] ) }gx;
print "$_\n" for @matches;
{capture|these|values}
[capture|these|values]
{[capture|these|values]|[capture|these|values]}
您显示的数据没有包含大括号的括号或包含括号的括号,但我怀疑对数据嵌套没有理论限制,在这种情况下需要进行一些递归
下面程序中的正则表达式模式定义了在里面一对匹配括号中的文本,作为管道分隔的序列
[ ... ]
{ ... }
capture
和values
在第二对捕获括号内的模式匹配。它是一种递归模式,使用相对编号(?-1)
来调用自身。这也可以是绝对编号(?2)
但如果前面的捕获数量发生变化则必须更改
完整模式在递归模式之前查找并捕获一系列单词字符,以便考虑cap1
,cap2
等。这样可以将glolbal搜索的结果直接分配给结果显示在下面的哈希
use strict;
use warnings;
my $s = "s|o|m|j|n|k|v|a|l|u|e|s|cap1{capture|these|values}|s|o|m|j|n|k|v|a|l|u|e|s|cap2[capture|these|values]|s|o|m|j|n|k|v|a|l|u|e|s|CAP3{[capture|these|values]|[capture|these|values]}";
my %captures = $s =~ m{
( (?> \w+ ) )
(
\{ (?-1) (?> \| (?-1) )* \} |
\[ (?-1) (?> \| (?-1) )* \] |
\w+
)
}gx;
use Data::Dump;
dd \%captures;
{
cap1 => "{capture|these|values}",
cap2 => "[capture|these|values]",
CAP3 => "{[capture|these|values]|[capture|these|values]}",
}
看起来您希望所有标识符前面都有一个竖线|
字符,后跟方括号或大括号[
或{
这个程序会为你做到这一点
use strict;
use warnings;
use v5.10;
my $s = "s|o|m|j|n|k|v|a|l|u|e|s|cap1{capture|these|values}|s|o|m|j|n|k|v|a|l|u|e|s|cap2[capture|these|values]|s|o|m|j|n|k|v|a|l|u|e|s|CAP3{[capture|these|values]|[capture|these|values]}";
for ( $s ) {
my @captures = /\|(\w+)[\[\{]/g;
say for @captures;
}
cap1
cap2
CAP3