0

我有一个字符串变量,其中包含类似ABCD.asd.qwe.com:/dir1. 我想提取ABCD部分,即从开始到第一次出现的部分.。问题是在.. 所以我创建了这个正则表达式。

if($arg =~ /(.*?\.?)/)
{
    my $temp_name = $1;
}

但是它给了我空白字符串。逻辑是:

.*? - any character non-greedily
\.? - till first or none appearance of .

有什么问题?

4

4 回答 4

3

您可以改为使用这样的否定字符类

^[^.]+

[^.]将匹配任何字符,除了.

[^.]+将匹配 1 到多个字符(除了.

^描述字符串的开头

或者

^.+?(?=\.|$)

(?=)是一个前瞻,它在当前位置之后检查特定模式。所以只有abcdad正则表达式的文本a(?=b)才会a匹配

$描述行尾(如果与多行选项一起使用)或字符串结尾(如果与单行选项一起使用)

于 2013-05-06T09:12:43.397 回答
3

\.?并不意味着“直到第一次出现或没有出现.”。它的意思是“.这里与否”。


如果字符串的第一个字符是.

  • .*?在位置 0 匹配 0 个字符。
  • \.?匹配位置 0 的 1 个字符。

$1包含..


如果字符串的第一个字符不是.

  • .*?在位置 0 匹配 0 个字符。
  • \.?在位置 0 匹配 0 个字符。

$1是空的。


要匹配ABCD,可以执行以下操作:

/^(.*?)\./

但是,我讨厌非贪婪修饰符。它很脆弱,从某种意义上说,如果您以相同的模式使用两个,它就会停止做您想做的事情。我会改用以下内容(“匹配非句点”):

/^([^.]*)\./

甚至只是

/^([^.]*)/
于 2013-05-06T09:19:05.533 回答
2
use strict;

my $string = "ABCD.asd.qwe.com:/dir1";

$string =~ /([^.]+)/;
my $capture = $1;
print"$capture\n";

或者您也可以使用拆分功能,例如,

my $sub_string = ( split /\./, $string )[0];
print"$sub_string\n";

一般注意:对于 Regex 的解释(理解复杂的 Regex),请查看YAPE::Regex::Explain模块。

于 2013-05-06T09:24:25.837 回答
0

这应该有效:

if($arg =~ /(.*?)\..+/)
{
    my $temp_name = $1; 
} 

这将匹配第一个之前的任何内容..+如果您的输入可能在第一个之后结束,您可以将 .* 更改为.。如果您确定在第一个之前总是至少有一个字符,您可以将第一个更改.*?为。.+?.

于 2013-05-06T09:27:00.313 回答