如何在一个字符串中匹配无,一个或两个值?

时间:2010-12-17 13:42:35

标签: regex perl

我有一个字符串,可以包含无,一个或两个值。如果有两个值,它们用冒号:分隔,如果第一个值应为空,则第二个值(唯一值)将以冒号作为前缀。

第一个值可以由几乎任何字符的字母数字和特殊字符组成,第二个值只能由字母数字字符组成。因此冒号不是一个独特的分隔符。

我尝试了一些正则表达式,大多数只能处理一个值,或者第一个没有冒号的两个值,但如果第一个是空的,则正则表达式将整个字符串作为第一个值返回。

我的实际代码如下:

if ($string =~ m/^(.+)(\:(\w+)|)$/){  
    $value1 = $1 || '';    
    if ($3){$value2 = $3}
}

这个适用于空字符串,只有第一个值,第一个值中没有冒号的两个值。

修改

字符串可以是:

  • Hello World!(只有一个值:value1 ='Hello World!')
  • This is a test:123(两个值:value1 ='这是测试'value2 ='123')
  • :Banana(只有一个值:value2 ='Banana')
  • T3-76:(只有一个值:value1 ='T3-76:')
  • Book:Title:Mysql(两个值:value1 ='Book:Title'value2 ='Mysql')

主要问题是如何在冒号后面包含冒号某些文本的一个值字符串与第一个值中没有冒号的两个值字符串之间产生差异。我应该假设,如果发生这种情况,它是一个双值字符串。

EDIT2

如果它更容易将代码修改为匹配空字符串。

有人有个主意吗?

4 个答案:

答案 0 :(得分:4)

也许使用带有前瞻性断言的split

my ($a, $b) = split(/:(?!.*:)/, $string);

请注意,空值可能是undef或空字符串。

答案 1 :(得分:1)

如果我理解正确,那么解释就不明确了。 考虑“1:2”。这可以解释为第一个值为1,第二个值为2.但是,由于第一个值可以包含特殊字符(例如“:”),因此这也可能被解释为第一个值为“1:2”。

您希望您的“口译员”在这种情况下如何工作?

编辑:

您是否考虑过使用拆分?它将返回一个数组。

如果数组为空=>字符串是空的。

如果数组大小为1 =>数组中的第一个元素是value1

如果数组有多个元素=>数组中的最后一个元素是value2,连接之前的所有其他元素都是value1。

这有帮助吗?

答案 2 :(得分:1)

试试这个:

^((?:(?!:[\w]*$).)*)(?::([\w]+)?)?$

答案 3 :(得分:0)

我会考虑使用if而不是一个正则表达式执行所有操作。也许是这样的:

if ( m/^(.*):([^:]*)$/ ) { $value1 = $1; $value2 = $2; }
else { $value1 = $_; $value2 = ''; }

重要的是,值-2只是字母数字,还是较弱(任何非结肠)测试?