仅按最后一个分隔符进行爆炸

时间:2013-05-17 13:52:48

标签: php

有没有办法使用explode函数仅在最后一个分隔符出现时爆炸?

$string = "one_two_  ... _three_four";

$explodeResultArray = explode("_", $string);

结果应该是:

$expoldeResultArray[0] is "one_two_three ...";

$expoldeResultArray[1] is "four";

11 个答案:

答案 0 :(得分:66)

直接的:

$parts = explode('_', $string);
$last = array_pop($parts);
$parts = array(implode('_', $parts), $last);
echo $parts[0]; // outputs "one_two_three"

正则表达式:

$parts = preg_split('~_(?=[^_]*$)~', $string);
echo $parts[0]; // outputs "one_two_three"

字符串反转:

$reversedParts = explode('_', strrev($string), 2);
echo strrev($reversedParts[0]); // outputs "four"

答案 1 :(得分:32)

无需解决方法。 explode()接受否定限制。

$string = "one_two_three_four";
$part   = implode('_', explode('_', $string, -1));
echo $part;

结果是

one_two_three

答案 2 :(得分:9)

您可以执行以下操作:

$string = "one_two_three_four";
$explode = explode('_', $string); // split all parts

$end = '';
$begin = '';

if(count($explode) > 0){
    $end = array_pop($explode); // removes the last element, and returns it

    if(count($explode) > 0){
        $begin = implode('_', $explode); // glue the remaining pieces back together
    }
}

编辑: array_shift应该是array_pop

答案 3 :(得分:9)

我选择使用子字符串,因为你想要一个特定点的字符串:

$string = "one_two_three_four_five_six_seven";
$part1 = substr("$string",0, strrpos($string,'_'));
$part2 = substr("$string", (strrpos($string,'_') + 1));
var_dump($part1,$part2);

结果:

string(27) "one_two_three_four_five_six"
string(5) "seven"

答案 4 :(得分:3)

<?php
$lastPos = strrpos($string, '_');
if ($lastPos !== false) {
    $start = substr($string, 0, $lastPos);
    $end = substr($string, $lastPos+1);
} else {
    // no delimeter found!
}

如果你只关心最后一部分,那就更简单了。

<?php
$end = substr(strrchr($string, '_'), 1);

答案 5 :(得分:3)

使用结束+爆炸

$explodeResultArray = end(explode("_", $string));

$ explodeResultArray will = 4

答案 6 :(得分:2)

使用preg_match()

$string = "one_two_three_four";

$arr = array();
preg_match("/(^.*)_(.*?)$/", $string, $arr);

print_r($arr);

输出: Array ( [0] => one_two_three_four [1] => one_two_three [2] => four )

答案 7 :(得分:2)

// reverse $string right after definition
$string = "one_two_three_four_five_six";
$string = implode("_",array_reverse(explode("_",$string)));

// chop off the first part
list($result, $string) = explode("_", $string, 2);

echo "$result --- $string";

输出:

six --- five_four_three_two_one 

答案 8 :(得分:1)

$explodeResultArray = explode("_", $string);
$last_item = end($explodeResultArray);
$key = count($explodeResultArray) - 1;
unset($explodeResultArray[$key]);
$arr[] = (implode($explodeResultArray,'_'));
$arr[] = $last_item;
print_r($arr);

<强>输出

Array
(
    [0] => one_two_  ... _three
    [1] => four
)

答案 9 :(得分:1)

我有类似的需求并且受到@NLZ's answer的启发我已经制作了具有与常规explode()相同功能的可重复使用的功能,但是向后(虽然我添加了一个选项来反转阵列顺序)常规explode()):

function backward_explode($delimiter, $string, $limit = null, $keep_order = true) {
    if ((string)$delimiter === "") {
        return false;
    }

    if ($limit === 0 || $limit === 1) {
        return array($string);
    }

    $explode = explode($delimiter, $string);

    if ($limit === null || $limit === count($explode)) {
        return $keep_order? $explode : array_reverse($explode);
    }

    $parts = array();

    if ($limit > 0) {
        for ($i = 1; $i < $limit; $i++) {
            $parts[] = array_pop($explode);
        }
        $remainder = implode($delimiter, $explode);
        $parts[] = $remainder;
        if ($keep_order) {
            $parts = array_reverse($parts);
        }
    } else {
        if (strpos($string, $delimiter) === false) {
            return array();
        }
        $parts = $explode;
        array_splice($parts, 0, abs($limit));
        if (!$keep_order) {
            $parts = array_reverse($parts);
        }
    }

    return $parts;
}

(Also as a gist.)

所以:

$string = 'one two three four';
var_dump(backward_explode(' ', $string));
var_dump(backward_explode(' ', $string, 2));
var_dump(backward_explode(' ', $string, 3));
var_dump(backward_explode(' ', $string, 2, false));
var_dump(backward_explode(' ', $string, -1));
var_dump(backward_explode(' ', $string, 1)); // same as with $limit = 0
var_dump(backward_explode('#', $string, -2));
var_dump(backward_explode('', $string, 3));

我们得到:

array (size=4)
  0 => string 'one' (length=3)
  1 => string 'two' (length=3)
  2 => string 'three' (length=5)
  3 => string 'four' (length=4)
array (size=2)
  0 => string 'one two three' (length=13)
  1 => string 'four' (length=4)
array (size=3)
  0 => string 'one two' (length=7)
  1 => string 'three' (length=5)
  2 => string 'four' (length=4)
array (size=2)
  0 => string 'four' (length=4)
  1 => string 'one two three' (length=13)
array (size=3)
  0 => string 'two' (length=3)
  1 => string 'three' (length=5)
  2 => string 'four' (length=4)
array (size=1)
  0 => string 'one two three four' (length=18)
array (size=0)
  empty
boolean false

答案 10 :(得分:0)

对于这样的任务,您可以只使用strstrstrrchr

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: maptilesbackend
  namespace: default
spec:
  selector:
    matchLabels:
      app: maptilesbackend
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: maptilesbackend
    spec:
      containers:
      - image: klokantech/openmaptiles-server
        imagePullPolicy: Always
        name: maptilesbackend
        volumeMounts:
          - mountPath: /data
            name: mapdata
            readOnly: true
      volumes:
        - name: mapdata
          persistentVolumeClaim:
            claimName: mapdata
            readOnly: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: "local-scsi"
provisioner: "kubernetes.io/no-provisioner"
volumeBindingMode: "WaitForFirstConsumer"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mapdata
spec:
  storageClassName: local-scsi
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 300Gi

话虽如此,我更喜欢正则表达式的答案。