我跟随字符串类型,
abc - xyz
abc - pqr - xyz
abc - - xyz
abc - pqr uvw - xyz
我想从第一个字符串中检索文本xyz
,从第二个字符串中检索pqr
,从第三个字符串中检索``(空) pqr uvw
。第二个连字符是可选的。 abc
是静态字符串,它必须在那里。我试过跟随正则表达式,
/^(?:abc) - (.*)[^ -]?/
但是它给了我以下输出,
xyz
pqr - xyz
- xyz
pqr uvw - xyz
我不需要第二个字符串中的最后一部分。我正在使用perl进行脚本编写。可以通过正则表达式完成吗?
答案 0 :(得分:3)
请注意(.*)
部分是一个贪婪量化的点,除了换行符之外,它尽可能多地抓取任何0 +字符,直到行的末尾和[^ -]?
,由于?
量词( 1或0重复)而能够匹配空字符串,匹配行尾的空字符串。因此,pqr - xyz
的{{1}}输出仅适用于正则表达式引擎。
您需要在此处使用更严格的模式。 E.g。
abc - pqr - xyz
请参阅regex demo。
<强>详情
/^abc\h*-\h*((?:[^\s-]+(?:\h+[^\s-]+)*)?)/
- 字符串的开头^
- abc
abc
- 用0+水平空格包围的连字符\h*-\h*
- 第1组捕获可选的出现次数
((?:[^\s-]+(?:\h+[^\s-]+)*)?)
- 除了空格和[^\s-]+
-
- 零次或多次重复
(?:\h+[^\s-]+)*
- 1+个水平空格\h+
- 除了空格和[^\s-]+
答案 1 :(得分:1)
您可以使用^[^-]*-\s*\K[^\s-]*
。
以下是它的工作原理:
^ # Matches at the beginning of the line (in multiline mode)
[^-]* # Matches every non - characters
- # Followed by -
\s* # Matches every spacing characters
\K # Reset match at current position
[^\s-]* # Matches every non-spacing or - characters
更新多个包含的字词:^[^-]*-\s*\K[^\s-]*(?:\s*[^\s-]+)*
最后一部分(?:\s*[^\s-]+)*
检查是否存在以空格开头的任何其他单词。
答案 2 :(得分:1)
您可以使用拆分:
$answer = (split / \- /, $t)[1];
其中$ t是文本字符串,你想要第二次分割(即[1]从0开始)。适用于除abc之外的所有内容 - - xyz,但如果分隔符是“ - ”,那么它应该在中间有2个空格不返回任何内容。如果abc - - xyz是正确的,那么你可以在分割之前完成所有工作:
$t =~ s/\- \-/- -/;
它只是插入一个额外的空格,因此它将匹配“ - ”两次,中间没有任何内容。
答案 3 :(得分:0)
可以通过正则表达式完成吗?
是的,有三个简单的正则表达式:-
和^\s+
以及\s+$
。
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
open my $INFILE, '<', 'data.txt';
my @results = map {
(undef, my $target) = split /-/, $_, 3;
$target =~ s/^\s+//; #remove leading spaces
$target =~ s/\s+$//; #remove trailing spaces
$target;
} <$INFILE>;
close $INFILE;
say Dumper \@results;
--output:--
$VAR1 = [
'xyz',
'pqr',
'',
'pqr uvw'
];