I have the following code but I'm not a big fan of reg exp as they are too confusing:
<?php
$r = '|\\*(.+)\\*|';
$w = '';
$s = 'hello world *copyMe* here';
function callbk($str){
print_r($str);
foreach($str as $k=>$v) {
echo $v;
}
}
$t = preg_replace_callback($r,'callbk',$s);
//output: Array ( [0] => *copyMe* [1] => copyMe ) *copyMe*copyMe
?>
my question is why is there both "*copyMe*" and "copyMe"?
i was hoping to get either one or the other, not both.
any help would be appriciated.
Because you are using a capturing expression (). If you omit the brackets you will only get *copyMe*.
Related
I have a pretty large array that I would need to parse, but the request changes depending on enabled/disabled parameters.
For example:
$array['a'][1]['b'][1]['c'][1] = 'asd';
$str = $array['a'][1];
dd($str);
This would give me:
Array
(
[b] => Array
(
[1] => Array
(
[c] => Array
(
[1] => asd
)
)
)
)
Which, of course, is correct. But now, if I know, that I need also the next parameter, I would need to add that like $str = $array['a'][1]['b'];.
But since there are way too many combinations, I wondered, if I can construct the call manually, something like this":
$str = $array['a'][1];
if ($b) {
$str .= ['b'][1];
}
if ($c) {
$str .= ['c'][1];
}
dd($str);
Any hints will be appreciated.
PS: I know I can do this with eval, but was really looking for a better solution:
eval("\$str = \$array$str;");
dd($str);
It can be done with Reference
$string = "['a'][1]['b'][1]";
// Maybe, not optimal, but it's not the point of the code
preg_match_all('/\[\'?([^\]\']+)\'?\]/', $string, $steps);
// "Root" of the array
$p = &$array;
foreach($steps[1] as $s) {
// Next step with current key
if (isset($p[$s]) && is_array($p)) $p = &$p[$s];
else throw new Exception("No such item");
}
// Target value
$str = $p;
demo
I have an Array like this
$first = array("10.2+6","5.3+2.2");
I want to convert it like this
$second = array("10+10+6","5+5+5+2+2");
I also want to print out this such as way
10
10
6
5
5
5
2
2
How can I do this?
You can use this preg_replace_callback function:
$first = array("10.2+6", "5.3+2.2");
$second = preg_replace_callback('/\b(\d+)\.(\d+)\b/', function($m){
$_r=$m[1]; for($i=1; $i<$m[2]; $i++) $_r .= '+' . $m[1] ; return $_r; }, $first);
print_r($second);
Output:
Array
(
[0] => 10+10+6
[1] => 5+5+5+2+2
)
We use this regex /\b(\d+)\.(\d+)\b/ where we match digits before and after DOT separately and capture them in 2 captured groups. Then in callback function we loop through 2nd captured group and construct our output by appending + and 1st captured group.
Here's a solution using regular expressions and various functions. There are many ways to accomplish what you're asking, and this is just one of them. I'm sure this could even be improved upon, but here it is:
$first = array("10.2+5","5.3+2.2");
$second = array();
$pattern = '/(\d+)\.(\d)/';
foreach($first as $item){
$parts = explode('+',$item);
$str = '';
foreach($parts as $part){
if(strlen($str)>0) $str .= '+';
if(preg_match_all($pattern, $part, $matches)){
$str .= implode("+", array_fill(0,$matches[2][$i], $matches[1][$i]));
}else{
$str .= $part;
}
}
$second[] = $str;
}
print_r($second);
Output:
Array
(
[0] => 10+10+5
[1] => 5+5+5+2+2
)
<?php
$first = array("10.2+5","5.3+2");
foreach($first as $term)
{
$second="";
$a=explode("+", $term);
$b=explode(".", $a[0]);
$c=$b[0];
for ($i=0;$i<$b[1];$i++)
$second=$second.$c."+";
echo $second.$a[1]."+";
}
?>
I have various values in a PHP array, that look like below:
$values = array("news_24", "news_81", "blog_56", "member_55", "news_27");
The first part before the underscore (news, blog, member) is dynamic so I would like to get all the matches in a specific section (news) followed by the numbers.
Something like below:
$section = "news";
$matches = preg_match('$section/[_])GETNUMBER/', $values);
This would return 24 and 27, but only where news was before the underscore.
Thanks.
$values = array("news_24", "news_81", "blog_56", "member_55", "news_27");
$section = "news";
foreach($values as $value) {
$matches = preg_match("/{$section}_(\\d+)/", $value, $number);
if ($matches)
echo $number[1], PHP_EOL;
}
$values = array("news_24", "news_81", "blog_56", "member_55", "news_27");
function func($type){
$results = null;
foreach($values as $val){
$curr = explode('_',$val);
if($curr[0]==$type){
$results[] = $curr[1];
}
}
return $results;
}
$News = func('news');
Good luck! :P
Note I added two cases:
$values = array ("news_24", "news_81", "blog_56", "member_55", "news_27",
"blognews_99", "news_2012_12");
$section = "news";
preg_match_all("/^{$section}_(\\d+)\$/m", implode("\n", $values), $matches);
print_r($matches[1]);
The implode might not be super efficient, but it's less code.
The difference is in the matching & regex.
This solution only outputs
Array
(
[0] => 24
[1] => 81
[2] => 27
)
While the others also output 2012 and the solution of Mark also 99.
I want to select specific words from a sentence according to my array list
$sentence = "please take this words only to display in my browser";
$list = array ("display","browser","words","in");
I want the output just like " words display in browser"
please somebody help me with this one. THX
I wonder if this one liner would do it :
echo join(" ", array_intersect($list, explode(" ",$sentence)));
Use at your own risk :)
edit : yay, it does the job, just tested
You can do it with preg_match:
$sentence = "please take this words only to display in my browser";
$list = array ("display","browser","words","in");
preg_match_all('/\b'.implode('\b|\b', $list).'\b/i', $sentence, $matches) ;
print_r($matches);
You'll get the words in order
Array
(
[0] => Array
(
[0] => words
[1] => display
[2] => in
[3] => browser
)
)
But be careful with regular expressions performance if the text is not that simple.
I don't know any short version for this rather than checking word by word.
$words = explode(" ", $sentence);
$new_sentence_array = array();
foreach($words as $word) {
if(in_array($word, $list)) {
$new_sentence_array[] = $word;
}
}
$new_sentece = implode(" ", $new_sentence_array);
echo $new_sentence;
I think you could search the string for each value in the array and assign it to a new array with the strpos value as the key; that would give you a sortable array that you could then output in the order that the terms appear in the string. See below, or example.
<?php
$sentence = "please take this words only to display in my browser";
$list = array ("display","browser","words","in");
$found = array();
foreach($list as $k => $v){
$position = strpos(strtolower($sentence), strtolower($v));
if($position){
$found[$position] = $v;
}
}
ksort($found);
foreach($found as $v){
echo $v.' ';
}
?>
$narray=array();
foreach ($list as $value) {
$status=stristr($sentence, $value);
if ($status) {
$narray[]=$value;
}
}
echo #implode(" ",$narray);
So here is the string that im scraping a page to read (using file get contents)
<th>Kills (K)</th><td><strong>4,751</strong></td><td><strong>0</strong></td>
How can i navigate to the above section of the page contents, and then isolate the 4,751 inside the above html and load it into $kills ?
Difficulty: the number will change and have additional numbers before the comma
Ok got it to work by removing all spaces and turning the page contents into a string
<?
$url = "http://combatarms.nexon.net/Community/Profile.aspx?user=tect0n";
$raw = file_get_contents($url);
$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B");
$content = str_replace($newlines, "", html_entity_decode($raw));
preg_match_all('|<th>.*?</th><td><strong>(\d+,\d+)</strong></td>|', $content,$match);
?>
This returns
Array ( [0] => Array ( [0] => Kills (K)4,751 [1] => Deaths (D)4,868 ) [1] => Array ( [0] => 4,751 [1] => 4,868 ) )
This should do it:
if (preg_match("/<th>Kills \(K\)<\/th><td><strong>([\d,]+)<\/strong>/",
$string, $matches)) {
$kills = str_replace(",","",$matches[1]);
} else {
$kills = 0;
}
This is what im using and gnarf's code returns 0
RageZ's returned an empty array
<?
$string = file_get_contents("http://combatarms.nexon.net/Community/Profile.aspx?user=tect0n");
if (preg_match("/<th>Kills \(K\)<\/th><td><strong>([\d,]+)<\/strong>/",
$string, $matches)) {
$kills = str_replace(",","",$matches[1]);
} else {
$kills = 0;
}
echo $kills;
?>
Coming up 0
here you go
preg_match_all('|<th>.*?</th><td><strong>([\d,]+)</strong></td>|x', $subject,$match);
var_dump($match);
but if I were you I would use xpath it's is safer.
preg_match_all('#\(K\).*?<strong>(.*?)</strong>#s',$html,$matches);
tell me that aint pretty
preg_match('#<table class="tbl_profile">(.*?)</table>#s',file_get_contents('http://combatarms.nexon.net/Community/Profile.aspx?user=tect0n'),$m);
preg_match_all('#<tr>.*?<t.*?>(.*?)</t.*?>.*?<t.*?>(.*?)</t.*?>.*?<t.*?>(.*?)</t.*?>.*?</tr>#s',preg_replace('#(<strong>)|(</strong>)|(<!--.*?-->)#s','',$m[1]),$r);
echo 'You got '.$r[2][1].' killz';
//print_r($r);
now tell me thaaaaaaat aint pretty, cooooool it.