I'm wondering if it is possible to truncate an array by using a regular expression.
我想知道是否可以通过使用正则表达式来截断一个数组。
In particular I have an array like this one:
我有一个这样的数组:
$array = array("AaBa","AaBb","AaBc","AaCa","AaCb","AaCc","AaDa"...);
I have this string:
我有这个字符串:
$str = "AC";
I'd like the slice of $array
from the start to the last occurrence of a string matching /A.C./
(in the sample, "AaCc" at index 5):
我希望$array的片段从字符串匹配/ a.c的开始到最后出现/(样本中索引5的“AaCc”):
$result = array("AaBa","AaBb","AaBc","AaCa","AaCb","AaCc");
How can I do this? I thought I might use array_slice
, but I don't know how to use a RegEx with it.
我该怎么做呢?我想我可能会使用array_slice,但是我不知道如何使用RegEx。
3 个解决方案
#1
4
Here's my bid
这是我的报价
function split_by_contents($ary, $pattern){
if (!is_array($ary)) return FALSE; // brief error checking
// keep track of the last position we had a match, and the current
// position we're searching
$last = -1; $c = 0;
// iterate over the array
foreach ($ary as $k => $v){
// check for a pattern match
if (preg_match($pattern, $v)){
// we found a match, record it
$last = $c;
}
// increment place holder
$c++;
}
// if we found a match, return up until the last match
// if we didn't find one, return what was passed in
return $last != -1 ? array_slice($ary, 0, $last + 1) : $ary;
}
Update
My original answer has a $limit
argument that served no purpose. I did originally have a different direction I was going to go with the solution, but decided to keep it simple. However, below is the version that implements that $limit
. So...
我最初的答案有一个没有任何意义的$limit论点。我本来有一个不同的方向,我打算采取的解决方案,但决定保持简单。但是,下面是实现这个$limit的版本。所以…
function split_by_contents($ary, $pattern, $limit = 0){
// really simple error checking
if (!is_array($ary)) return FALSE;
// track the location of the last match, the index of the
// element we're on, and how many matches we have found
$last = -1; $c = 0; $matches = 0;
// iterate over all items (use foreach to keep key integrity)
foreach ($ary as $k => $v){
// text for a pattern match
if (preg_match($pattern, $v)){
// record the last position of a match
$last = $c;
// if there is a specified limit, capture up until
// $limit number of matches, then exit the loop
// and return what we have
if ($limit > 0 && ++$matches == $limit){
break;
}
}
// increment position counter
$c++;
}
#2
1
I think the easiest way might be with a foreach loop, then using a regex against each value - happy to be proven wrong though!
我认为最简单的方法可能是使用foreach循环,然后对每个值使用regex—但是很高兴被证明是错误的!
One alternative could be to implode the array first...
一种选择可能是先内爆数组……
$array = array("AaBa","AaBb","AaBc","AaCa","AaCb","AaCc","AaDa"...);
$string = implode('~~',$array);
//Some regex to split the string up as you want, guessing something like
// '!~~A.C.~~!' will match just what you want?
$result = explode('~~',$string);
If you'd like a hand with the regex I can do, just not 100% on exactly what you're asking - the "A*C*"-->"AaCc"
bit I'm not too sure on?
如果你想和regex合作,我可以做,但不能100%完全按照你的要求——“a *C*”——>“AaCc”bit我不太确定?
#3
1
Assuming incremental numeric indices starting from 0
假设增量数字索引从0开始
$array = array("AaBa","AaBb","AaBc","AaCa","AaCb","AaCc","AaDa");
$str = "AC";
$regexpSearch = '/^'.implode('.',str_split($str)).'.$/';
$slicedArray = array_slice($array,
0,
array_pop(array_keys(array_filter($array,
function($entry) use ($regexpSearch) {
return preg_match($regexpSearch,$entry);
}
)
)
)+1
);
var_dump($slicedArray);
PHP >= 5.3.0 and will give a
PHP >= 5.3.0,将给出a
Strict standards: Only variables should be passed by reference
严格的标准:仅通过引用传递变量
And if no match is found, will still return the first element.
如果没有找到匹配,仍然返回第一个元素。
#1
4
Here's my bid
这是我的报价
function split_by_contents($ary, $pattern){
if (!is_array($ary)) return FALSE; // brief error checking
// keep track of the last position we had a match, and the current
// position we're searching
$last = -1; $c = 0;
// iterate over the array
foreach ($ary as $k => $v){
// check for a pattern match
if (preg_match($pattern, $v)){
// we found a match, record it
$last = $c;
}
// increment place holder
$c++;
}
// if we found a match, return up until the last match
// if we didn't find one, return what was passed in
return $last != -1 ? array_slice($ary, 0, $last + 1) : $ary;
}
Update
My original answer has a $limit
argument that served no purpose. I did originally have a different direction I was going to go with the solution, but decided to keep it simple. However, below is the version that implements that $limit
. So...
我最初的答案有一个没有任何意义的$limit论点。我本来有一个不同的方向,我打算采取的解决方案,但决定保持简单。但是,下面是实现这个$limit的版本。所以…
function split_by_contents($ary, $pattern, $limit = 0){
// really simple error checking
if (!is_array($ary)) return FALSE;
// track the location of the last match, the index of the
// element we're on, and how many matches we have found
$last = -1; $c = 0; $matches = 0;
// iterate over all items (use foreach to keep key integrity)
foreach ($ary as $k => $v){
// text for a pattern match
if (preg_match($pattern, $v)){
// record the last position of a match
$last = $c;
// if there is a specified limit, capture up until
// $limit number of matches, then exit the loop
// and return what we have
if ($limit > 0 && ++$matches == $limit){
break;
}
}
// increment position counter
$c++;
}
#2
1
I think the easiest way might be with a foreach loop, then using a regex against each value - happy to be proven wrong though!
我认为最简单的方法可能是使用foreach循环,然后对每个值使用regex—但是很高兴被证明是错误的!
One alternative could be to implode the array first...
一种选择可能是先内爆数组……
$array = array("AaBa","AaBb","AaBc","AaCa","AaCb","AaCc","AaDa"...);
$string = implode('~~',$array);
//Some regex to split the string up as you want, guessing something like
// '!~~A.C.~~!' will match just what you want?
$result = explode('~~',$string);
If you'd like a hand with the regex I can do, just not 100% on exactly what you're asking - the "A*C*"-->"AaCc"
bit I'm not too sure on?
如果你想和regex合作,我可以做,但不能100%完全按照你的要求——“a *C*”——>“AaCc”bit我不太确定?
#3
1
Assuming incremental numeric indices starting from 0
假设增量数字索引从0开始
$array = array("AaBa","AaBb","AaBc","AaCa","AaCb","AaCc","AaDa");
$str = "AC";
$regexpSearch = '/^'.implode('.',str_split($str)).'.$/';
$slicedArray = array_slice($array,
0,
array_pop(array_keys(array_filter($array,
function($entry) use ($regexpSearch) {
return preg_match($regexpSearch,$entry);
}
)
)
)+1
);
var_dump($slicedArray);
PHP >= 5.3.0 and will give a
PHP >= 5.3.0,将给出a
Strict standards: Only variables should be passed by reference
严格的标准:仅通过引用传递变量
And if no match is found, will still return the first element.
如果没有找到匹配,仍然返回第一个元素。