2010-12-17 131 views
2

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

第一值可以由任何漂亮字符的字母数字和特殊字符,第二值唯一的字母数字字符的。因此冒号不是一个明显的分隔符。

我尝试了一些正则表达式,然而他们的工作罚款只有一个值,或两个值,而在第一冒号,但如果第一个是空的正则表达式返回整个字符串作为第一个值。

我的实际代码如下所示:

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

这一个适用于空字符串,只有第一个值,没有第一个值结肠两个值。

编辑

字符串可能是:

  • Hello World!(只有一个值:数值=的 'Hello World!')
  • This is a test:123(两个值:数值='这是一个test'value2 ='123')
  • :Banana(只有一个值:value2 ='香蕉')
  • T3-76:(只有一个值:VALUE1 = 'T3-76:')
  • Book:Title:Mysql(两个值:VALUE1 = '图书:名称' 值='MySQL的)

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

EDIT2

如果它可以更容易的代码可以修改匹配一个空字符串。

有人有想法吗?

+0

查看问题的编辑的版本 – Pit 2010-12-17 14:03:17

+0

您如何知道“abc:def”是否是一个值(包含:)或两个值之间用?隔开的值? – ysth 2010-12-17 18:49:45

+0

看到亚历山大的回答和我对它的评论 – Pit 2010-12-19 21:07:22

回答

4

也许使用split用式断言:

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

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

+0

似乎工作,我将只需要确保你说的未定义的字符串,谢谢。 – Pit 2010-12-17 14:30:53

1

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

你怎么能指望你的“解释”在这种情况下工作吗?

编辑:

你有没有想过使用拆分?它会返回一个数组。

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

如果数组的大小为1 =>数组第一元件被VALUE1

如果阵列具有多个元素=>最后一个元素在阵列是值2,而在这之前级联所有其它元素是VALUE1。

这有帮助吗?

+0

正如在我的问题的编辑版本中提到的,我想我将不得不假设它是一个两值字符串。或者,也许我必须通过一些不能包含在第一个值中的特殊分隔符来分隔字符串中的两个值。我只是不知道我可以使用哪一个 – Pit 2010-12-17 13:58:55

+0

我将使用Peter提供的'split'解决方案,但是您的解释有助于处理未定义的值。谢谢。 – Pit 2010-12-17 14:42:15

1

试试这个:

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

它不符合第二个值,应该是$ 5? – Pit 2010-12-17 14:18:58

+0

如果在第一部分中出现:之前我改变了它,然后它不匹配。你的意思是5美元? – morja 2010-12-17 14:28:40

+0

我的意思是由第5个括号对匹配的值 – Pit 2010-12-17 14:43:37

0

我会考虑用if而不是做一切正则表达式。也许是这样的:

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

是很重要的是价值2只字母,或者是较弱(什么也没-一个冒号)测试OK?

相关问题