Match string that contains two "needles" - php

I have a string that looks a little like this
1: u:mads g:folk 2: g:andre u:jens u:joren
what I need is a way (I'm guessing by regex) to get for instance u:jens and the number (1 or 2) it is after.
how do I go about this in php (preferably with just one function)?

This will find all matches. If you only need the first, use preg_match instead.
<?php
$subject = '1: u:mads g:folk 2: g:andre u:jens u:joren 3: u:jens';
preg_match_all('#(\d+):[^\d]*?u:jens#msi', $subject, $matches);
foreach ($matches[1] as $match) {
var_dump($match);
}
?>

You can use the following regex:
(\d+):(?!.*\d+:.*).*u:jens
Where the digit you're looking for is put in the first capturing group. So, if you're using PHP:
$matches = array();
$search = '1: u:mads g:folk 2: g:andre u:jens u:joren';
if (preg_match('/(\d+):(?!.*\d+:.*).*u:jens/', $search, $matches)) {
echo 'Found at '.$matches[1]; // Will output "Found at 2"
}

This will parse the string and return an array containing the number keys in which the search string was found:
function whereKey($search, $key) {
$output = array();
preg_match_all('/\d+:[^\d]+/', $search, $matches);
if ($matches[0]) {
foreach ($matches[0] as $k) {
if (strpos($k, $key) !== FALSE) {
$output[] = (int) current(split(':', $k));
}
}
}
return $output;
}
For example:
whereKey('1: u:mads g:folk 2: g:andre u:jens u:joren', 'u:jens')
...will return:
array(1) { [0]=> int(2) }

Related

manipulating array to use in different contex

I am using regex to match pattern. Then pushing matched result using pushToResultSet. In both way of doing, would $resultSet have similar array content? Similar means not
insense of value, but format. I want to use 2nd way in alternative to 1st code.
UPDATE: Example with sample input http://ideone.com/lIaP49
foreach ($words as $word){
$pattern = '/^(?:\((\+?\d+)?\)|(\+\d{0,3}))? ?\d{2,3}([-\.]?\d{2,3} ?){3,4}/';
preg_match_all($pattern, $text, $matches, PREG_OFFSET_CAPTURE );
$this->pushToResultSet($matches);
}
return $resultSet;
Now I am doing this in another way and pushing array in similar way. As $matches is array and here $b is also array, I guess both code are similar
$b = array();
$pattern = '/^(?:\((\+?\d+)?\)|(\+\d{0,3}))? ?\d{2,3}([-\.]?\d{2,3} ?){3,4}/';
foreach ($test as $value)
{
$value = strtolower($value);
// Capture also the numbers so we just concat later, no more string substitution.
$matches = preg_split('/(\d+)/', $value, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
if ($matches)
{
$newValue = array();
foreach ($matches as $word)
{
// Replace if a valid word number.
$newValue[] = (isset($arrwords[$word]) ? $arrwords[$word] : $word);
}
$newValue = implode($newValue);
if (preg_match($pattern, $newValue))
{
$b[] = $value;
$this->pushToResultSet($b);
}
}
}
//print_r($b);
return $resultSet;
UPDATE
ACtual code which I want to replace out with 2nd code in the question:
<?php
class Phone extends Filter{
function parse($text, $words)
{
$arrwords = array(0=>'zero',1=>'one',2=>'two',3=>'three',4=>'four',5=>'five',6=>'six',7=>'seven',8=>'eight',9=>'nine');
preg_match_all('/[A-za-z]+/', $text, $matches);
$arr=$matches[0];
foreach($arr as $v)
{
$v = strtolower($v);
if(in_array($v,$arrwords))
{
$text= str_replace($v,array_search($v,$arrwords),$text);
}
}
//$resultSet = array();
$l = strlen($text);
foreach ($words as $word){
$pattern = '/^(?:\((\+?\d+)?\)|(\+\d{0,3}))? ?\d{2,3}([-\.]?\d{2,3} ?){3,4}/';
preg_match_all($pattern, $text, $matches, PREG_OFFSET_CAPTURE );
//print_r($matches);
}
//print_r($matches);
$this->pushToResultSet($matches);
return $resultSet;
}
}
After running both codes, run PHP's var_dump function on the output variables.
If the printed output matches for your definition of similar array content, then your answer is yes. Otherwise, your answer is no.

Using a list with regex in 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"
// }

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.

Search for PHP array element containing string [duplicate]

This question already has answers here:
Filter multidimensional array based on partial match of search value
(3 answers)
Closed 1 year ago.
$example = array('An example','Another example','Last example');
How can I do a loose search for the word "Last" in the above array?
echo array_search('Last example',$example);
The code above will only echo the value's key if the needle matches everything in the value exactly, which is what I don't want. I want something like this:
echo array_search('Last',$example);
And I want the value's key to echo if the value contains the word "Last".
To find values that match your search criteria, you can use array_filter function:
$example = array('An example','Another example','Last example');
$searchword = 'last';
$matches = array_filter($example, function($var) use ($searchword) { return preg_match("/\b$searchword\b/i", $var); });
Now $matches array will contain only elements from your original array that contain word last (case-insensitive).
If you need to find keys of the values that match the criteria, then you need to loop over the array:
$example = array('An example','Another example','One Example','Last example');
$searchword = 'last';
$matches = array();
foreach($example as $k=>$v) {
if(preg_match("/\b$searchword\b/i", $v)) {
$matches[$k] = $v;
}
}
Now array $matches contains key-value pairs from the original array where values contain (case- insensitive) word last.
function customSearch($keyword, $arrayToSearch){
foreach($arrayToSearch as $key => $arrayItem){
if( stristr( $arrayItem, $keyword ) ){
return $key;
}
}
}
$input= array('An example','Another example','Last example');
$needle = 'Last';
$ret = array_keys(array_filter($input, function($var) use ($needle){
return strpos($var, $needle) !== false;
}));
This will give you all the keys whose value contain the needle.
It finds an element's key with first match:
echo key(preg_grep('/\b$searchword\b/i', $example));
And if you need all keys use foreach:
foreach (preg_grep('/\b$searchword\b/i', $example) as $key => $value) {
echo $key;
}
The answer that Aleks G has given is not accurate enough.
$example = array('An example','Another example','One Example','Last example');
$searchword = 'last';
$matches = array();
foreach($example as $k=>$v) {
if(preg_match("/\b$searchword\b/i", $v)) {
$matches[$k] = $v;
}
}
The line
if(preg_match("/\b$searchword\b/i", $v)) {
should be replaced by these ones
$match_result = preg_match("/\b$searchword\b/i", $v);
if( $match_result!== false && $match_result === 1 ) {
Or more simply
if( preg_match("/\b$searchword\b/i", $v) === 1 ) {
In agreement with http://php.net/manual/en/function.preg-match.php
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
I do not like regex because as far as I know, they are always slower than a normal string function. So my solution is:
function substr_in_array($needle, array $haystack)
{
foreach($haystack as $value)
{
if(strpos($value, $needle) !== FALSE) return TRUE;
}
return FALSE;
}
I was also looking for a solution to OP's problem and I stumbled upon this question via Google. However, none of these answers did it for me so I came up with something a little different that works well.
$arr = array("YD-100 BLACK", "YD-100 GREEN", "YD-100 RED", "YJ-100 BLACK");
//split model number from color
$model = explode(" ",$arr[0])
//find all values that match the model number
$match_values = array_filter($arr, function($val,$key) use (&$model) { return stristr($val, $model[0]);}, ARRAY_FILTER_USE_BOTH);
//returns
//[0] => YD-100 BLACK
//[1] => YD-100 GREEN
//[2] => YD-100 RED
This will only work with PHP 5.6.0 and above.

How to get pattern matching in php array using RegEx

I have following set of an array
array('www.example.com/','www.example.com','www.demo.example.com/','www.example.com/blog','www.demo.com');
and I would like to get all element which matching following patterns,
$matchArray = array('*.example.com/*','www.demo.com');
Expected result as
array('www.example.com/','www.demo.example.com/','www.example.com/blog','www.demo.com');
Thanks :)
This works:
$valuesArray = array('www.example.com/','www.example.com','www.demo.example.com/','www.example.com/blog','www.demo.com');
$matchArray = array('*.example.com/*','www.demo.com');
$matchesArray = array();
foreach ($valuesArray as $value) {
foreach ($matchArray as $match) {
//These fix the pseudo regex match array values
$match = preg_quote($match);
$match = str_replace('\*', '.*', $match);
$match = str_replace('/', '\/', $match);
//Match and add to $matchesArray if not already found
if (preg_match('/'.$match.'/', $value)) {
if (!in_array($value, $matchesArray)) {
$matchesArray[] = $value;
}
}
}
}
print_r($matchesArray);
But I would reccomend changing the syntax of your matches array to be actual regex patterns so that the fix section of code is not required.
/\w+(\.demo)?\.example\.com\/\w*|www\.demo\.com/
regexr link

Categories