Php 标签分隔字符串的正则表达式

Php 标签分隔字符串的正则表达式,php,regex,Php,Regex,我有很多这样的字符串: a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc Array ( [0] => A [1] => AAX1AAY222 [2] => B [3] => BBX4BBY555BBZ6 [4] => C [5] => MMM1 [6] => D [7] => ARA1 [8] => E [9] =&g

我有很多这样的字符串:

a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc
Array
(
    [0] => A
    [1] => AAX1AAY222
    [2] => B
    [3] => BBX4BBY555BBZ6
    [4] => C
    [5] => MMM1
    [6] => D
    [7] => ARA1
    [8] => E
    [9] => ABC
)
C#mmm1D#ara1
我需要做的是根据
hashtag
位置将它们拆分为如下内容:

a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc
Array
(
    [0] => A
    [1] => AAX1AAY222
    [2] => B
    [3] => BBX4BBY555BBZ6
    [4] => C
    [5] => MMM1
    [6] => D
    [7] => ARA1
    [8] => E
    [9] => ABC
)
C#mmm1D#ara1
因此,正如您看到的,
hashtag后面的字符
被捕获,加上hashtag后面的所有内容,就在下一个char+hashtag之前

我有下面的
RegEx
,当我在每个部分的末尾有一个
数值时,它可以正常工作

以下是正则表达式设置:

preg_split('/([A-Z])+#/', $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
它可以很好地处理这样的事情:

a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc
Array
(
    [0] => A
    [1] => AAX1AAY222
    [2] => B
    [3] => BBX4BBY555BBZ6
    [4] => C
    [5] => MMM1
    [6] => D
    [7] => ARA1
    [8] => E
    [9] => ABC
)
C#mmm1D#ara1
但是,如果我将其更改为此(删除数字):

那么结果会是不好的:

    Array
(
    [0] => C
    [1] => D
)
我已经看了一个问题和一个问题,它们都很相似,但都不适合我

所以,我的问题是,为什么它只有在后面跟一个数字时才起作用?我怎样才能解决它

在这里,您可以看到一些示例字符串,我有:

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.S.字符串不区分大小写

p.p.S.如果你想知道这些字符串到底是什么,它们是用户提交的问卷答案,我不能对它们做任何重构之类的事情,因为它们已经存储好了,只需要继续

为什么不使用explode?

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

更新

我们是否应该关注为什么
/([A-Z])+#/
只在包含数字的情况下起作用?谢谢。

使用explode()而不是Regexp

$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];
$tmpArray=explode(#“,“a#aax1aay222b#bbx4bby555bbz6c#mmm1d#ara1e#abc”);
$myArray=array();
对于($i=0;$i

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

而不是使用
preg\u split()
,而是决定要匹配的内容:

  • 如果后跟

    此表达式使用两个前瞻断言。结果显示在
    $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
    )
    
    您可以使用
    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)

    如果仍要使用preg\u split,可以删除
    +
    ,它可能会按预期工作:

    '/([A-Z])#/i'
    
    从那时起,您只匹配hashtag和一个alpha字符,而不是所有字符

    例如:



    编辑:在模式中添加了一个不区分大小写的标志
    i

    @senk我还需要捕获#之前的字符。您可以
    explode()
    并复制上一个数组项中的最后一个字符。@Voitcus您可以尝试一下并将其作为答案发布吗?我还是不明白你想如何用explode捕捉那个角色。谢谢。这很让人困惑,你能不能设置不同的分隔符,你能不能把字符串做成这样:“a#aax1aay222,b#bbx4bby555bbz6,c#mmm1,d#ara1,e#abc”@nacholibre我当然可以用一些技巧来做;找到#,在
    -2
    位置上放置一个
    ,但老实说我不喜欢这样做…目标是在自己的数组元素中捕获
    前面的字符;重读这个问题。@nl-x嗯,正如我上面提到的,我正在努力避免在我的项目中编写棘手的代码。但谢谢你的努力。:)@nl-x+1因为你的努力:)那太完美了。。。非常感谢你的帮助!你知道我的正则表达式出了什么问题吗?
    Jack
    ,顺便说一句,我选择
    Marcus
    作为接受答案,因为这正好解决了我在问题中提出的问题,但再次感谢你的回答@在大多数情况下,Mahdi可以将
    preg_split()
    转换为
    preg_match_all()
    ;在我看来,这使得遵循逻辑变得更容易,即使在这里实际上可以使用
    preg_split()
    。你是对的,但我的意思是因为
    Marcus
    正是在修复我的正则表达式,看起来简单多了,我选择了他的答案作为接受。我认为他的解决方案也更有效。我仍然喜欢你构造正则表达式的方式,但我相信如果我采用他的解决方案会更公平。@Mahdi效率应该永远是最后一个要考虑的问题,但Marcus的回答很好:)@Jack也许你需要关注最后一部分。当
    explode
    返回单个字符时,这也会插入空字符串,也许应该删除它们。感谢您的努力。。。但是你知道,最近我试图避免编程中的技巧,我相信对于每一个问题都有(至少)一个合适的解决方案。查看
    Jack
    的答案:)@Voitcus感谢您的努力:)哇,这很好。。。也谢谢你的解释@Mahdi您可能希望使用A-Za-z0-9使小写/大写字母一起工作(如您的示例中所示),如果您希望使用数字(如更新中所示)@Marcus更新您的答案,以便答案的代码与链接的代码匹配