Using a list with regex in php - php

$word = file('list.txt');
$content = file_get_contents('fleetyfleet.txt');
fleetyfleet.txt contains
DimensionNameGreenrandomjunktextextcstuffidonwantDimensionNameBluemoreeecrapidontwannaseeeDimensionNameYellowDimensionNameGrayrandomcrapDimensionNameRed
list.txt contains
Green Blue Yellow
what i want is to be able to find DimensionName then store the word after it into an array if the word is in list.txt
so when script was ran the result stored in array would be Green,Blue,Yellow but not Red and Gray because they are not in our list

Explode your word list, then loop over it:
$word = file_get_contents('list.txt');
$content = file_get_contents('fleetyfleet.txt');
$found_dimensions = array(); // our array
$word_array = explode(' ', $word); // explode the list
foreach($word_array as $one_word) { // loop over it
$str = 'DimensionName'.$one_word; // what are we looking for?
if(strstr($content, $str) !== false) { // look for it!
echo "Found $one_word<br/>"; // Just for demonstration purposes
$found_dimensions[] = $one_word; // add to the array
}
}

The trick is to explode() your file contents by delimiter and then filter results with the words from the list. $matching contains all found fragments matching list.
$words = file_get_contents('list.txt');
$text = file_get_contents('content.txt');
$elements = explode('DimensionName', $text); // trick
$words = explode(' ', $words); // words list
// leverage native PHP function
$matching = array_reduce($elements, function($result, $item) use($words) {
if(in_array($item, $words)) { $result[] = $item; }
return $result;
}, array());
var_dump($matching);
UPDATE
array_reduce() is a neat function, but I totally forgot about a way simpler solution:
$matching = array_intersect($words, $elements);
From the docs:
array_intersect() returns an array containing all the values of array1 that are present in all the arguments. Note that keys are preserved.
So $matching will contain all elements from $words array that are present in $elements. This is the simplest and possibly the best solution here.

I think this is what you wanted..I loop through each word in list.txt, and then use a preg_match() to see if that dimension is in fleetyfleet.txt (you don't need a regex for my example, but I left it in case your example is more complicated). If it matches, then I add the match to your array of $dimensions.
<?php
$dimensions = array();
$content = 'DimensionNameGreenrandomjunktextextcstuffidonwantDimensionNameBluemoreeecrapidontwannaseeeDimensionNameYellowDimensionNameGrayrandomcrapDimensionNameRed';
$list = 'Green Blue Yellow';
foreach(explode(' ', $list) as $word) {
if(preg_match('/DimensionName' . trim($word) . '/', $content, $matches) {
$dimensions[] = reset($matches);
}
}
var_dump($dimensions);
// array(3) {
// [0]=> string(18) "DimensionNameGreen"
// [1]=> string(17) "DimensionNameBlue"
// [2]=> string(19) "DimensionNameYellow"
// }

Related

Retrieve word from string

I have this code:
$getClass = $params->get('pageclass_sfx');
var_dump($getClass); die();
The code above returns this:
string(24) "sl-articulo sl-categoria"
How can I retrieve the specific word I want without mattering its position?
Ive seen people use arrays for this but that would depend on the position (I think) that you enter these strings and these positions may vary.
For example:
$myvalue = $params->get('pageclass_sfx');
$arr = explode(' ',trim($myvalue));
echo $arr[0];
$arr[0] would return: sl-articulo
$arr[1] would return: sl-categoria
Thanks.
You can use substr for that in combination with strpos:
http://nl1.php.net/substr
http://nl1.php.net/strpos
$word = 'sl-categoria';
$page_class_sfx = $params->get('page_class_sfx');
if (false !== ($pos = strpos($page_class_sfx, $word))) {
// stupid because you already have the word... But this is what you request if I understand correctly
echo 'found: ' . substr($page_class_sfx, $pos, strlen($word));
}
Not sure if you want to get a word from the string if you already know the word... You want to know if it's there? false !== strpos($page_class_sfx, $word) would be enough.
If you know exactly what strings you're looking for, then stripos() should be sufficient (or strpos() if you need case-sensitivity). For example:
$myvalue = $params->get('pageclass_sfx');
$pos = stripos($myvalue, "sl-articulo");
if ($pos === FALSE) {
// string "sl-articulo" was not found
} else {
// string "sl-articulo" was found at character position $pos
}
If you need to check if some word are in string you may use preg_match function.
if (preg_match('/some-word/', 'many some-words')) {
echo 'some-word';
}
But this solution can be used for a small list of needed words.
For other cases i suggest you to use some of this.
$myvalue = $params->get('pageclass_sfx');
$arr = explode(' ',trim($myvalue));
$result = array();
foreach($arr as $key=> $value) {
// This will calculates all data in string.
if (!isset($result[$value])) {
$result[$value] = array(); // or 0 if you don`t need to use positions
}
$result[$value][] = $key; // For all positions
// $result[$value] ++; // For count of this word in string
}
// You can just test some words like follow:
if (isset($result['sl-categoria'])) {
var_dump($result['sl-categoria']);
}

Converting an array into a string

I am doing an assignment on how to take a string of text separated by commas and reverse the individual words and return the words in the same order.
This code does that but it is not returning it as a string for some reason and i do not understand.
<?php
function bassAckwards($input)
{
// YOUR CODE HERE
$commas = substr_count($input, ",");
$NumWords = ($commas + 1);
$words = array($input);
for($x=0;$x<$NumWords;$x++)
{
$answer = array(strrev($words[$x]));
$answer = implode(",",$answer);
print $answer;
}
}
?>
function bassAckwards($str){
$words = explode(',', $str);
$reversedWords = array_map('strrev', $words);
return implode(',', $reversedWords);
}
var_dump(bassAckwards('foo,bar,baz')); // string(11) "oof,rab,zab"
Save yourself some headaches and use the built-it functions.
explode
make 'foo,bar,baz' => array('foo','bar','baz')
array_map & strrev
Execute strrev (string reverse) on every element of the array with array_map and return the [modified] array back.
implode
convert the array back to a csv.
$reversedWords = array();
// Explode by commas
$words = explode(',', $input);
foreach ($word in $words) {
// For each word
// Stack it, reversed, in the new array $reversedWords
$reversedWords[] = strrev($word);
}
// Implode by commas
$output = implode(',', $reversedWords);
print $output;

substr() function for array PHP

I have a code that will produce array of strings.... now my problem is i need to substr each result of the array but i think array is not allowed to be used in substr...
please help:
CODE:
<?php
$file = 'upload/filter.txt';
$searchfor = $_POST['search'];
$btn = $_POST['button'];
$sum = 0;
if($btn == 'search') {
//prevents the browser from parsing this as HTML.
header('Content-Type: text/plain');
// get the file contents, assuming the file to be readable (and exist)
$contents = file_get_contents($file);
// escape special characters in the query
$pattern = preg_quote($searchfor, '/');
// finalise the regular expression, matching the whole line
$pattern = "/^.*$pattern.*\$/m";
// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)){
echo "Found matches:\n";
$result = implode("\n", $matches[0]);
echo $result;
}
else{
echo "No matches found";
}
}
?>
The $matches there is the array... i need to substr each result of the $matches
you can use array_walk:
function fcn(&$item) {
$item = substr(..do what you want here ...);
}
array_walk($matches, "fcn");
Proper use of array_walk
array_walk( $matches, substr(your area));
Array_map accepts several arrays
array_map(substr(your area), $matches1, $origarray2);
in your case
array_map(substr(your area), $matches);
Read more:
array_map
array_walk
To find a sub string in an array I use this function on a production site, works perfectly.
I convert the array to a collection because it's easier to manage.
public function substrInArray($substr, Array $array) {
$substr = strtolower($substr);
$array = collect($array); // convert array to collection
return $body_types->map(function ($array_item) {
return strtolower($array_item);
})->filter(function ($array_item) use ($substr) {
return substr_count($array_item, $substr);
})->keys()->first();
}
This will return the key from the first match, it's just an example you can tinker. Returns null if nothing found.

Regex hash and colons

I want to use regular expression to filter substrings from this string
eg: hello world #level:basic #lang:java:php #...
I am trying to produce an array with a structure like this:
Array
(
[0]=> hello world
[1]=> Array
(
[0]=> level
[1]=> basic
)
[2]=> Array
(
[0]=> lang
[1]=> java
[2]=> php
)
)
I have tried preg_match("/(.*)#(.*)[:(.*)]*/", $input_line, $output_array);
and what I have got is:
Array
(
[0] => hello world #level:basic #lang:java:php
[1] => hello world #level:basic
[2] => lang:java:php
)
In this case then I will have to apply this regex few times to the indexes and then apply a regex to filter the colon out. My question is: is it possible to create a better regex to do all in one go? what would the regex be? Thanks
You can use :
$array = explode("#", "hello world #level:basic #lang:java:php");
foreach($array as $k => &$v) {
$v = strpos($v, ":") === false ? $v : explode(":", $v);
}
print_r($array);
do this
$array = array() ;
$text = "hello world #level:basic #lang:java:php";
$array = explode("#", $text);
foreach($array as $i => $value){
$array[$i] = explode(":", trim($value));
}
print_r($array);
Got something for you:
Rules:
a tag begins with #
a tag may not contain whitespace/newline
a tag is preceeded and followed by whitespace or line beginning/ending
a tag can have several parts divided by :
Example:
#this:tag:matches this is some text #a-tag this is no tag: \#escaped
and this one tag#does:not:match
Function:
<?php
function parseTags($string)
{
static $tag_regex = '#(?<=\s|^)#([^\:\s]+)(?:\:([^\s]+))*(?=\s|$)#m';
$results = array();
preg_match_all($tag_regex, $string, $results, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
$tags = array();
foreach($results as $result) {
$tag = array(
'offset' => $result[0][1],
'raw' => $result[0][0],
'length' => strlen($result[0][0]),
0 => $result[1][0]);
if(isset($result[2]))
$tag = array_merge($tag, explode(':', $result[2][0]));
$tag['elements'] = count($tag)-3;
$tags[] = $tag;
}
return $tags;
}
?>
Result:
array(2) {
[0]=>array(7) {
["offset"]=>int(0)
["raw"]=>string(17) "#this:tag:matches"
["length"]=>int(17)
[0]=>string(4) "this"
[1]=>string(3) "tag"
[2]=>string(7) "matches"
["elements"]=>int(3)
}
[1]=>array(5) {
["offset"]=>int(36)
["raw"]=>string(6) "#a-tag"
["length"]=>int(6)
[0]=>string(5) "a-tag"
["elements"]=>int(1)
}
}
Each matched tag contains
the raw tag text
the tag offset and original length (e.g. to replace it in the string later with str... functions)
the number of elements (to safely iterate for($i = 0; $i < $tag['elements']; $i++))
This might work for you:
$results = array() ;
$text = "hello world #level:basic #lang:java:php" ;
$parts = explode("#", $text);
foreach($parts as $part){
$results[] = explode(":", $part);
}
var_dump($results);
Two ways using regex, note that you somehow need explode() since PCRE for PHP doesn't support capturing a subgroup:
$string = 'hello world #level:basic #lang:java:php';
preg_match_all('/(?<=#)[\w:]+/', $string, $m);
foreach($m[0] as $v){
$example1[] = explode(':', $v);
}
print_r($example1);
// This one needs PHP 5.3+
$example2 = array();
preg_replace_callback('/(?<=#)[\w:]+/', function($m)use(&$example2){
$example2[] = explode(':', $m[0]);
}, $string);
print_r($example2);
This give you the array structure you are looking for:
<pre><?php
$subject = 'hello world #level:basic #lang:java:php';
$array = explode('#', $subject);
foreach($array as &$value) {
$items = explode(':', trim($value));
if (sizeof($items)>1) $value = $items;
}
print_r($array);
But if you prefer you can use this abomination:
$subject = 'hello world #level:basic #lang:java:php';
$pattern = '~(?:^| ?+#)|(?:\G([^#:]+?)(?=:| #|$)|:)+~';
preg_match_all($pattern, $subject, $matches);
array_shift($matches[1]);
$lastKey = sizeof($matches[1])-1;
foreach ($matches[1] as $key=>$match) {
if (!empty($match)) $temp[]=$match;
if (empty($match) || $key==$lastKey) {
$result[] = (sizeof($temp)>1) ? $temp : $temp[0];
unset($temp);
}
}
print_r($result);

is there a native php function to see if one array of values is in another array?

Is there a better method than loop with strpos()?
Not i'm looking for partial matches and not an in_array() type method.
example needle and haystack and desired return:
$needles[0] = 'naan bread';
$needles[1] = 'cheesestrings';
$needles[2] = 'risotto';
$needles[3] = 'cake';
$haystack[0] = 'bread';
$haystack[1] = 'wine';
$haystack[2] = 'soup';
$haystack[3] = 'cheese';
//desired output - but what's the best method of getting this array?
$matches[0] = 'bread';
$matches[1] = 'cheese';
ie:
magic_function($haystack, %$needles%) !
foreach($haystack as $pattern) {
if (preg_grep('/'.$pattern.'/', $needles)) {
$matches[] = $pattern;
}
}
I think you are confusing $haystack and $needle in your question, because naan bread is not in haystack, nor is cheesestring. Your desired output suggests you are looking for cheese in cheesestring instead. For that, the following would work:
function in_array_multi($haystack, $needles)
{
$matches = array();
$haystack = implode('|', $haystack);
foreach($needles as $needle) {
if(strpos($haystack, $needle) !== FALSE) {
$matches[] = $needle;
}
}
return $matches;
}
For your given haystack and needles this performs twice as fast as a regex solution. Might change for different number of params though.
I think you'll have to roll your own. The User Contributed Comments to array_intersect() provide a number of alternative implementations (like this one). You would just have to replace the == matching against strstr().
$data[0] = 'naan bread';
$data[1] = 'cheesestrings';
$data[2] = 'risotto';
$data[3] = 'cake';
$search[0] = 'bread';
$search[1] = 'wine';
$search[2] = 'soup';
$search[3] = 'cheese';
preg_match_all(
'~' . implode('|', $search) . '~',
implode("\x00", $data),
$matches
);
print_r($matches[0]);
// [0] => bread
// [1] => cheese
You'll get better answers if you tell us more about the real problem.

Categories