如何使这个奇怪的字符串在PHP中爆炸?

时间:2016-04-15 11:24:47

标签: php regex grep

我有一个像以下

的字符串
DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]

上面的字符串是一种格式化的组,如下所示:

A-B[C]-D-E-[F]-G-[H]

我认为我喜欢处理其中的一些群体,而且我喜欢做类似爆炸的事情。

我想说,因为我试过这段代码:

$string = 'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]';
$parts = explode( '-', $string );
print_r( $parts );

我得到以下结果:

Array
(
    [0] => DAS
    [1] => 1111[DR
    [2] => Helpfull
    [3] => R]
    [4] => RUN
    [5] => 
    [6] => [121668688374]
    [7] => N
    [8] => [+helpfull_+string]
)

这不是我需要的。

我需要的是以下输出:

Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
)

有人可以建议一种漂亮而优雅的方式以我需要的方式爆炸这个字符串吗?

我忘了提到的是,字符串可以有更多或更少的组。例子:

DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]
DAS-1111[DR-Helpfull-R]-RUN--[121668688374]
DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart

更新1

如@axiac所述,preg_split可以完成工作。但是,你现在能帮助正则表达式吗?

我试过这个,但似乎不正确:

(?!\]\-)\-

3 个答案:

答案 0 :(得分:5)

代码:

$str = 'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]';
$re  = '/([^-[]*(?:\[[^\]]*\])?[^-]*)-?/';

$matches = array();
preg_match_all($re, $str, $matches);
print_r($matches[1]);

其输出:

Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] =>
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
    [7] =>
)

输出中位置7有一个额外的空值。这似乎是因为?末尾的零或一重复量词(regex)。需要量词,因为没有它,最后一块(在索引6)不匹配。

您可以在上一个?之后移除-,并以这种方式询问短划线(-)是否始终匹配。在这种情况下,您必须在输入字符串中添加额外的-

正则表达式

(              # start of the 1st subpattern
               # the captured value is returned in $matches[1]
  [^-[]*       # match any character but '-' and '[', zero or more times
  (?:          # start of a non-capturing subpattern
    \[         # match an opening square bracket ('[')
    [^\]]*     # match any character but ']', zero or more times
    \]         # match a closing square bracket (']')
  )?           # end of the subpattern; it is optional (can appear 0 or 1 times)
  [^-]*        # match any character but '-', zero or more times
)              # end of the 1st subpattern
-?             # match an optional dash ('-')

答案 1 :(得分:2)

不应爆炸,而应尝试匹配以下模式:

$regex = '/(?:^|-)([^-\[]*(?:\[[^\]]+\])?)/';
$tests = array(
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]',
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]',
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart'
);
foreach ($tests as $test) {
    preg_match_all($regex, $test, $result);
    print_r($result[1]);
}

Here is an example

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]
Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
)

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]
Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
)

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart
Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
    [7] => anotherPart
)

输出:

$(document).ready(function() {
  $("#submit").click(function(e) {
    var result = $('#salesPrice').val() - $('#costPrice').val();
    $("#profitOut").text(result);
  });
});

答案 2 :(得分:1)

这种情况非常适合(*SKIP)(*FAIL)方法。您希望将字符串拆分在连字符上,只要它们不在方括号内。

易。只是取消这些连字符作为分隔符的资格:

模式:~\[[^]]+\](*SKIP)(*FAIL)|-~Pattern Demo

代码:(Demo

$strings=['DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]',
          'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]',
          'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart'];

foreach($strings as $string){
    var_export(preg_split('~\[[^]]+\](*SKIP)(*FAIL)|-~',$string));
    echo "\n\n";
}

输出:

array (
  0 => 'DAS',
  1 => '1111[DR-Helpfull-R]',
  2 => 'RUN',
  3 => '',
  4 => '[121668688374]',
  5 => 'N',
  6 => '[+helpfull_+string]',
)

array (
  0 => 'DAS',
  1 => '1111[DR-Helpfull-R]',
  2 => 'RUN',
  3 => '',
  4 => '[121668688374]',
)

array (
  0 => 'DAS',
  1 => '1111[DR-Helpfull-R]',
  2 => 'RUN',
  3 => '',
  4 => '[121668688374]',
  5 => 'N',
  6 => '[+helpfull_+string]',
  7 => 'anotherPart',
)