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.
Related
this is my code that extracts the date "2016-06-13" from the string "ffg_LTE_2016-06-13"
$re = '/(\d{8})|([0-9]{4}-[0-9]{2}-[0-9]{2})|([0-9]{2}-[0-9]{2}-[0-9]{4})/';
$str = "ffg_LTE_2016-06-13";
preg_match($re, $str, $matches);
$date=$matches[0];
print_r($date);
Now what I want to do is do somthing like this in a for loop but I am having issues with storing the result in an array. What I want to do is the same as above but do it on each elememt in the array.
$files=["ffg_LTE_2016-06-13","ffg_LTE_2016-06-14"];
foreach ($files as $value) {
print_r("<br>".$value."<br>");
}
So my end result would be
$files_2=["2016-06-13","2016-06-14"];
here is my fiddle
You can try this:
<?php
$files=["ffg_LTE_2016-06-13","ffg_LTE_2016-06-14"];
$re = '/(\d{8})|([0-9]{4}-[0-9]{2}-[0-9]{2})|([0-9]{2}-[0-9]{2}-[0-9]{4})/';
$results = [];
foreach ($files as $value) {
preg_match($re, $value, $matches);
$results[] = $matches[0];
}
print_r($results);
?>
It just loops through $files, pushes the first match into the array $results, and prints out $results.
transactionid=67002 msisdn=12136018066 destination_msisdn=12136018066 country=Canada countryid=701 operator=1Canada operatorid=2350 reference_operator= originating_currency=CAD destination_currency=CAD product_requested=3 actual_product_sent=3 wholesale_price=3.61 retail_price=3.70 balance=9.96 sms_sent=no sms= cid1= cid2= cid3= pin_based=yes pin_option_1=key in : *105* (top-up code) # (press call button) pin_option_2=Click the WIND icon on your phone pin_option_3=to access the menu, and top up in a few quick steps pin_value=3 pin_code=9973 44700 7583 pin_ivr= pin_serial=5500000008 pin_validity=365 authentication_key=1455826552 error_code=0 error_txt=Transaction Good
When we make this into an array we dont want to lose values like pin_code that has spaces within the data like the delimiter of the string which is also a space. Here is my code so far:
$parsed = preg_split('/\s+/',$string);
$page_is = array_shift($parsed_url);
$getVars = array();
foreach($parsed as $argument) {
list($variable,$value) = explode("=",$argument); $getVars[$variable] = $value;
}
The following approach worked for me:
$str = "transactionid=67002 msisdn=12136018066 destination_msisdn=12136018066 country=Canada countryid=701 operator=1Canada operatorid=2350 reference_operator= originating_currency=CAD destination_currency=CAD product_requested=3 actual_product_sent=3 wholesale_price=3.61 retail_price=3.70 balance=9.96 sms_sent=no sms= cid1= cid2= cid3= pin_based=yes pin_option_1=key in : *105* (top-up code) # (press call button) pin_option_2=Click the WIND icon on your phone pin_option_3=to access the menu, and top up in a few quick steps pin_value=3 pin_code=9973 44700 7583 pin_ivr= pin_serial=5500000008 pin_validity=365 authentication_key=1455826552 error_code=0 error_txt=Transaction Good" ;
$parts = explode('=', $str);
$key = array_shift($parts);
$last_value = array_pop($parts);
foreach($parts as $part) {
preg_match('/[a-zA-Z0-9_]+$/', $part, $match);
$next_key = $match[0];
$value = str_replace($next_key, '', $part);
$array[$key] = $value;
$key = $next_key;
}
$array[$key] = $last_value;
$array = array_map('trim', $array);
var_dump($array);
fun with regular expressions:
$regex = '/(\w+)=((?:.(?!\w+=))+)/';
preg_match_all($regex, $str, $matches, PREG_SET_ORDER);
var_dump($matches);
and if you have php 5.5 or greater you can place this cherry on top (bottom)
$values = array_combine(array_column($matches, 1), array_column($matches, 2));
var_cump($values);
I have a string like:
'word1 \nword2 "word3 \nword4" word5 \nword6'
and I want to became like
'word1
word2 "word3 \nword4" word5
word6'
I couldn't write any success regexp pattern. Is this possible ?
You can use preg_split for this task:
$result = preg_split('/"[^"]*"(*SKIP)(*FAIL)|\s*\\n\s*/', $txt);
You obtain the parts you want in an array, you can make all what you want after. (write a file line by line, implode with a CRLF...)
More informations about (*SKIP) and (*FAIL): Verbs that act after backtracking and failure
It's possible by regex, my way is kinda complex, maybe someone has better solution
$subject = <<<'SUBJECT'
'word1 \nword2 "special \n \"character" word5 \nword6'
SUBJECT;
$callback = function ($matches1) {
if (preg_match_all(
<<<PATTERN
/"(?:\"|[^"])+?"/
PATTERN
, $matches1[0], $matches2, PREG_OFFSET_CAPTURE)) {
$pointer = 0;
$arr = [];
foreach ($matches2[0] as $match2) {
$arr[] = substr($matches1[0], $pointer, $match2[1]);
$arr[] = $match2[0];
$pointer = $match2[1] + strlen($match2[0]);
}
$arr[] = substr($matches1[0], $pointer, strlen($matches1[0]));
foreach ($arr as $key => &$value) {
if (!($key % 2)) {
$value = preg_replace('/\Q\n\E/', "\n", $value);
}
}
return implode('', $arr);
}
return $matches1[0];
};
$result = preg_replace_callback(
<<<PATTERN
/'(?:\'|[^'])+?'/
PATTERN
, $callback, $subject);
file_put_contents('doc.txt', $result);
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) }
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