在多个单词上爆炸字符串

时间:2015-11-20 16:28:34

标签: php arrays regex explode

有一个这样的字符串:

$string = 'connector:rtp-monthly direction:outbound message:error writing data: xxxx yyyy zzzz date:2015-11-02 10:20:30';

此字符串来自用户输入。所以它永远不会有相同的订单。它是一个输入字段,我需要将其拆分以构建数据库查询。

现在我想基于array()中给出的单词拆分字符串,这就像一个包含我需要在字符串中找到的单词的映射器。看起来像这样:

$mapper = array(
    'connector' => array('type' => 'string'),
    'direction' => array('type' => 'string'),
    'message' => array('type' => 'string'),
    'date' => array('type' => 'date'),
);

只有$mapper的密钥才有用。我试过foreach并且像以下一样爆炸:

 $parts = explode(':', $string);

但问题是:字符串中可能有冒号,所以我不需要在那里爆炸。如果在映射器键之后紧跟冒号,我只需要爆炸。在这种情况下,映射器键是:

connector    // in this case split if "connector:" is found
direction    // untill "direction:" is found
message      // untill "message:" is found
date         // untill "date:" is found

但请记住,用户输入也可以。所以字符串将始终以字符串的顺序改变,mapper array()将永远不会以相同的顺序。因此,我不确定爆炸是否是正确的方法,或者我是否应该使用正则表达式。如果是这样的话怎么做。

所需的结果应该是一个如下所示的数组:

$desired_result = array(
    'connector' => 'rtp-monthly',
    'direction' => 'outbound',
    'message' => 'error writing data: xxxx yyyy zzzz',
    'date' => '2015-11-02 10:20:30',
);

非常感谢帮助。

5 个答案:

答案 0 :(得分:2)

这个棘手的部分是匹配原始字符串。您可以在lookahead positive assertions的帮助下使用Regex执行此操作:

$pattern = "/(connector|direction|message|date):(.+?)(?= connector:| direction:| message:| date:|$)/";
$subject = 'connector:rtp-monthly direction:outbound message:error writing data: xxxx yyyy zzzz date:2015-11-02 10:20:30';

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER );

$returnArray = array();
foreach($matches as $item)
{
    $returnArray[$item[1]] = $item[2];
}

在此正则表达式/(connector|direction|message|date):(.+?)(?= connector:| direction:| message:| date:|$)/中,您正在匹配:

  • (connector|direction|message|date) - 找到关键字并抓取它;
  • : - 后跟冒号;
  • (.+?) - 其次是任何不贪婪的角色,并抓住它;
  • (?= connector:| direction:| message:| date:|$) - 直到下一个关键字或字符串结尾,使用非捕获前瞻肯定断言。

结果是:

Array
(
    [connector] => rtp-monthly
    [direction] => outbound
    [message] => error writing data: xxxx yyyy zzzz
    [date] => 2015-11-02 10:20:30
)

我没有使用mapper数组只是为了使示例清晰,但您可以使用implode将关键字放在一起。

答案 1 :(得分:0)

我们的目标是创建一个包含我们将从字符串中提取的两个数组的值的数组。有两个数组是必要的,因为我们希望考虑两个字符串分隔符。 试试这个:

$parts = array();
$large_parts = explode(" ", $string);

for($i=0; $i<count($large_parts); $i++){
    $small_parts = explode(":", $large_parts[$i]);
    $parts[$small_parts[0]] = $small_parts[1];
}

$parts现在应该包含所需的数组

希望你得到整理。

答案 2 :(得分:0)

您可以使用正则表达式和explode()的组合。请考虑以下代码:

$str = "connector:rtp-monthly direction:outbound message:error writing data date:2015-11-02";
$regex = "/([^:\s]+):(\S+)/i";
// first group: match any character except ':' and whitespaces
// delimiter: ':'
// second group: match any character which is not a whitespace
// will not match writing and data
preg_match_all($regex, $str, $matches);
$mapper = array();
foreach ($matches[0] as $match) {
    list($key, $value) = explode(':', $match);
    $mapper[$key][] = $value;
}

此外,您可能想要考虑一种更好的方式来存储字符串(JSON?XML?)。

答案 3 :(得分:0)

你在这里。正则表达式是&#34; catch&#34;键(任何字符序列,不包括空格和&#34;:&#34;)。从那里开始,我使用&#34; explode&#34;到了#34;递归&#34;拆分字符串。经测试的广告效果很好

$string = 'connector:rtp-monthly direction:outbound message:error writing data date:2015-11-02';

$element = "(.*?):";
preg_match_all( "/([^\s:]*?):/", $string, $matches);
$result = array();
$keys = array();
$values = array();
$counter = 0;
foreach( $matches[0] as $id => $match ) {
    $exploded = explode( $matches[ 0 ][ $id ], $string );
    $keys[ $counter ] = $matches[ 1 ][ $id ];
    if( $counter > 0 ) {
        $values[ $counter - 1 ] = $exploded[ 0 ];
    }
    $string = $exploded[ 1 ];
    $counter++;
}
$values[] = $string;
$result = array();
foreach( $keys as $id => $key ) {
    $result[ $key ] = $values[ $id ];
}
print_r( $result );

答案 4 :(得分:0)

在PHP中通过多个分隔符将preg_split()用作explode()

这里只是一个简短的说明。要使用PHP中的多个定界符来爆炸()字符串,您必须使用正则表达式。使用竖线字符分隔定界符。

$string = 'connector:rtp-monthly direction:outbound message:error writing data: xxxx yyyy zzzz date:2015-11-02 10:20:30';
$chunks = preg_split('/(connector|direction|message)/',$string,-1, PREG_SPLIT_NO_EMPTY);

// Print_r to check response output.
echo '<pre>';
print_r($chunks);
echo '</pre>';

PREG_SPLIT_NO_EMPTY –仅返回非空件。