2013-05-06 92 views
0

我有一个字符串变量,包含类似ABCD.asd.qwe.com:/dir1。 我想提取ABCD部分,即从.开始到第一次出现的部分。问题是在.之前几乎可以有任何长度的字符(只有字母数字)。所以我创建了这个正则表达式。Perl正则表达式提取子字符串?

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

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

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

什么可能是错的?

+0

您是否尝试提取'ABCD'或'ABCD.'?输入中是否会出现'.'? – ikegami 2013-05-06 09:25:18

+0

我想只提取ABCD,不包括点。 – 2013-05-06 09:28:56

+0

我的第二个问题呢。输入中是否总会有'.'? – ikegami 2013-05-06 10:08:15

回答

3

您可以改用负字符类这样

^[^.]+ 

[^.]将匹配除了.

[^.]+任何字符将匹配1对多字符(除.

^描绘了字符串

的开始

OR

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

(?=)是一个超前,检查当前position..So之后的特定模式的文本abcdad用正则表达式a(?=b)a将匹配

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

+0

嗨@Anirudh,这两个解决方案都在工作! 谢谢你! 但是,你能解释一下这背后的逻辑吗? – 2013-05-06 09:19:24

+0

@Cool_Coder逻辑非常简单。第一个'^'的意思是“'字符串必须从这里开始”。下一个'[^。] +'是指“任何不是一个周期的字符,重复一次或多次。”因此,它会选择直到第一个周期。 – h2ooooooo 2013-05-06 09:23:20

+0

@Cool_Coder检查编辑... @酷感谢 – Anirudha 2013-05-06 09:24:15

3

\.?并不意味着“直到第一个或没有出现.”。这意味着“在这里或不是”.


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

  • .*?比赛在位置0 0字符
  • \.?比赛1个炭在位置0

$1包含.


如果字符串的第一个字符不是.:在位置在位置0 0

  • \.?比赛0字符

    • .*?比赛0字符。

    $1为空。


    要匹配ABCD,下面会做:

    /^(.*?)\./ 
    

    不过,我最讨厌的非贪婪修改。它是脆弱的,从某种意义上说,如果你使用两个相同的模式,它会停止做你想做的事。我会使用,而不是下面的( “匹配非周期”):

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

    甚至只是

    /^([^.]*)/ 
    
  • +0

    ('^'不是必需的,但这是一个好习惯,因为它可以防止失败时出现疯狂的回溯。) – ikegami 2013-05-06 09:24:27

    +0

    感谢您解释我最初的方法的不正确性。 – 2013-05-06 10:01:18

    2
    use strict; 
    
    my $string = "ABCD.asd.qwe.com:/dir1"; 
    
    $string =~ /([^.]+)/; 
    my $capture = $1; 
    print"$capture\n"; 
    

    ,或者您也可以使用Split功能一样,

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

    注意一般:为了解释正则表达式(理解comple x正则表达式),看看YAPE::Regex::Explain模块。

    +0

    感谢分割方法:) – 2013-05-06 09:33:13

    +1

    '我($捕获)= $字符串=〜/^([^.]+)/;'会更强大。 (奖金:不使用全局变量。) – ikegami 2013-05-06 09:37:18

    +0

    对,同意。谢谢 – 2013-05-06 09:39:14

    0

    这应该工作:

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

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

    +0

    添加'。+'是无用的。首先,它和'.'一样。其次,它所做的一切就是确保'.'后面跟着一个非换行符,并且OP没有表示任何兴趣来验证。那么为什么要添加它? – ikegami 2013-05-06 09:36:12