2013-05-16 104 views
5

我有一串字符串是这样的:正则表达式包括hashtag分隔的字符串

a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc 

而我需要做的是一个基于hashtag位置,这样的事情对他们分裂:

Array 
(
    [0] => A 
    [1] => AAX1AAY222 
    [2] => B 
    [3] => BBX4BBY555BBZ6 
    [4] => C 
    [5] => MMM1 
    [6] => D 
    [7] => ARA1 
    [8] => E 
    [9] => ABC 
) 

因此,正如您看到hashtag后面的字符被加上加上紧随下一个char + hashtag之前的hashtag之后的所有内容。

我有以下RegEx哪些工作正常只有当我有一个numeric值在每个部分的结尾。

这里是正则表达式设置:

preg_split('/([A-Z])+#/', $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 

并能正常工作像这样的东西:

C#mmm1D#ara1 

但是,如果我把它改成这样(删除号码):

C#mmmD#ara 

那么这将是结果,这是不好的:

Array 
(
    [0] => C 
    [1] => D 
) 

我看过this问题和this其中一个也是类似的,但都没有为我工作。

所以,我的问题是为什么它只有在后面跟着一个数字才有效?以及我如何解决它?

在这里你可以看到,我有一些他们的样本串:

a#123b#abcc#def456   // A:123, B:ABC, C:DEF456 
a#abc1def2efg3b#abcdefc#8 // A:ABC1DEF2EFG3, B:ABCDEF, C:8 
a#abcdef123b#5c#xyz789  // A:ABCDEF123, B:5, C:XYZ789 

附:字符串不区分大小写。

P.P.S.如果你想过这些字符串究竟是什么,它们是用户提交的调查问卷的答案,我不能对它们做任何重构,因为它们已经存储并且只需要继续。

为什么不使用爆炸?

如果你看看我的例子,你会发现我需要在#之前捕获角色。如果您认为可以使用explode(),请发布输出,谢谢!

更新

要着重如果包含数字,为什么/([A-Z])+#/仅适用?谢谢。

+2

为什么不爆炸()? – senK

+0

@senk我需要在#之前捕捉角色。 – Mahdi

+0

你可以'爆炸()'并复制前一个数组项中的最后一个字符。 – Voitcus

回答

4

如果你仍然想使用使preg_split可以去除+,并预期它可能工作:

'/([A-Z])#/i' 

从此以后你之前只匹配主题标签,一个字母字符,而不是全部。

实施例:http://codepad.viper-7.com/z1kFDb

编辑:添加了不区分大小写的标志i在图案。

+0

但它不是这样的工作:'c#abcd# xyz' – Mahdi

+0

@Mahdi,抱歉张贴错误的链接。看到正确的链接。 – Marcus

+0

哇,这是工作很好...感谢您的解释也! – Mahdi

1

使用爆炸(),而不是正则表达式

$tmpArray = explode("#","a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc"); 
$myArray = array(); 
for($i = 0; $i < count($tmpArray) - 1; $i++) { 
    if (substr($tmpArray[$i],0,-1)) $myArray[] = substr($tmpArray[$i],0,-1); 
    if (substr($tmpArray[$i],-1)) $myArray[] = substr($tmpArray[$i],-1); 
} 
if (count($tmpArray) && $tmpArray[count($tmpArray) - 1]) $myArray[] = $tmpArray[count($tmpArray) - 1]; 

编辑:我更新了我的答案,以反映更好的阅读问题

+0

目标是捕获自己数组元素中'#'前面的字符;重读这个问题。 – Vulcan

+0

@Vulcan谢谢,真的。 – Mahdi

+0

@Mahdi我更新了我的答案 –

6

而不是使用preg_split()的,决定你想匹配的内容:

  1. 一组“单词”,如果后面跟着<any-char>#<end-of-string>

  2. 一个字符,如果紧跟着#

    $str = 'a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc'; 
    
    preg_match_all('/\w+(?=.#|$)|\w(?=#)/', $str, $matches); 
    

Demo

这个表达式使用两个先行断言。结果在$matches[0]

更新

的看着这将是它的另一方式:

preg_match_all('/(\w)#(\w+)(?=\w#|$)/', $str, $matches); 

print_r(array_combine($matches[1], $matches[2])); 

每个条目与单个字符,后跟一个散列,然后用X字符,直到任月底开始遇到字符串或下一个条目的开始。

输出是这样的:

Array 
(
    [a] => aax1aay222 
    [b] => bbx4bby555bbz6 
    [c] => mmm1 
    [d] => ara1 
    [e] => abc 
) 
+0

这是完美的! ... 非常感谢您的帮助!你知道我的正则表达式有什么问题吗? – Mahdi

+0

'杰克',顺便说一句,我选择'马库斯'答案被接受,因为这是解决我在问题中提出的确切问题,但非常感谢您的回答! – Mahdi

+0

@Mahdi在大多数情况下,'preg_split()'可以变成'preg_match_all()';在我看来,它使得更容易遵循逻辑,即使'preg_split()'实际上可能在这里。 –

0

您可以使用explode()功能,将分割字符串除了散的迹象,就像在之前给出的答案说。

$myArray = explode("#",$string); 

对于字符串 'A#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#ABC' 这将返回类似

$myarray = array('a', 'aax1aay22b', 'bbx4bby555bbz6c' ....); 

你现在需要的是把每个字符串的最后一个字符数组另一个项目。

$copy = array(); 
foreach($myArray as $item){ 
    $beginning = substr($item,0,strlen($item)-1); // this takes all characters except the last one 
    $ending = substr($item,-1); // this takes the last one 
    $copy[] = $beginning; 
    $copy[] = $ending; 
} // end foreach 

这是一个示例,未经过测试。

编辑

而不是substr($item,0,strlen($item)-1);你可以使用substr($item,0,-1);

+0

不适用于最后一部分; '#abc'变成'ab'和'c'。 –

+0

@杰克也许你需要连接最后一部分。当'explode'返回单个字符时,这也会插入空字符串,也许它们应该被删除。 – Voitcus

+0

感谢您的努力......但您知道,最近我试图避免编程中的技巧,我相信每个问题总是[至少]一个适当的解决方案。检查出杰克的答案以及:) – Mahdi

相关问题