Fastest approach to deconstructing string - php

I have a php string of the form :
somename_XXX_someothername_YYY
XXX & YYY = Integers
I want to extract somename and XXX in an array, such that:
array [0] => somename
array [1] => XXX
Following is my approach of achieving it:
$a = array();
$x = 'stack_312_overflow_213';
$a[] = strstr($x, '_', true);
$a[] = strstr(ltrim(strstr($x, '_', false), '_'), '_', true);
I wanted to know if there way any other faster way of doing it as my application will be trimming about 10,000+ strings in this way.
P.S.: I don't know much about speeds, or which php functions are the fastest, so thought of posting it here.

Faster then explode and preg_match:
list($word, $num) = sscanf($x, '%[^_]_%d');
Also you will have $num as integer already.
If you are willing to use explode, limit it with 3 to speed it up, also you will lose time on casting int on $num if you need it:
explode('_', $x, 3);

Just use $arr = explode('_', $str); and the values in the [0] and [1] spot are the first two values you requested

Below are two ways you can get the information from the string.
Which one of the two is faster? I really have no idea, but you can test it.
This result is from the explode:
$result = explode('_', 'somename_XXX_someothername_YYY', 3);
print_r($result);
Using a regular expression:
$matches = array();
preg_match('/^(.*?)_(.*?)_/', 'somename_XXX_someothername_YYY', $matches);
array_shift($matches); //will remove the first match, which is "somename_XXX_"
print_r($matches);

Related

How to get a range of arrays

I have a code which I have to explode my text using "*" as a delimiter.
I have a pattern that always the array [0] and [1] will be excluded and the rest of them need to be included inside a variable, but my problem is that I don't know how to catch dynamically the rest of the arrays that I have to put them all together inside of it.
Specially because my text may have more "*" and explode into more parts, but I have to get them all together. Excluding the [0] and [1]
$item= explode("*",$c7);
print_r($item);
//so now that I know which are my [0] and [1] arrays I need to get the rest of them inside of another variable
$variable = ?? //the rest of the $item arrays
$str = 'a*b*c*d*e';
$newStr = implode('*', array_slice(explode('*', $str), 2)); // OUTPUT: c*d*e
explode() is used to chunk the string by a delimiter
implode() is used to build a string again from chunks
array_slice() is used to select a range of the elements
I realise an answer was already accepted, but explode has a third argument for this, and with end you can grab that last, non-split part:
$str = 'a*b*c*d*e';
$res = end(explode("*", $str, 3));
$res gets this value as a result:
c*d*e
I think based off of your question, if I interpreted it correctly something like below will be useful.
USING A LOOP
$str = "adssa*asdASD*AS*DA*SD*ASD*AS*DAS*D";
$parts = explode("*", $str);
$newStr = "";
for ($i = 2; $i < count($parts); ++$i) {
$newStr .= $parts[$i];
}

How to sort words in alphabetical order from a sentence, not array

I'm trying to take sentences from a user and storing them to compare them later, but i want them to be alphabetial, like;
Apple
Banana
taken from a string like, "Banana, Oranges And Apples"; So before that i first cut the words i don't want but i don't know how I'll go about sorting since PHP sort() seems to only work on array
<?php
$str = 'Man Methord Wifi HOlla Teddy Husband';
$result = trim( preg_replace(
"/[^a-z0-9']+([a-z0-9']{1,5}[^a-z0-9']+)*/i",
" ",
" $str "
) );
$lower_str = strtolower ($result);
echo $lower_str;
?>
This function may work for you :
function sortstring($string,$unique = false) {
$string = str_replace('.', '', $string);
$array = explode(' ',strtolower($string));
if ($unique) $array = array_unique($array);
sort($array);
return implode(' ',$array);
}
You can find this function and its example usage at http://www.wordinn.com/solution/226/php-sort-words-sentences
It has got an easy function that is called sort().In sort function, there are many type of different sort algorithms working on sort function.This function has got 2 parameters.First parameter of sort function is array which will be sort and Second one is about type of sort algorithm.
<?php
$data = array("a","k","b","z","i","v");
sort($data,SORT_STRING);
print_r($data);
?>

How to use explode and get first element in one line in PHP?

$beforeDot = explode(".", $string)[0];
This is what I'm attempting to do, except that it returns syntax error. If there is a workaround for a one liner, please let me know. If this is not possible, please explain.
The function array dereferencing was implemented in PHP 5.4, so if you are using an older version you'll have to do it another way.
Here's a simple way to do it:
$beforeDot = array_shift(explode('.', $string));
You can use list for this:
list($first) = explode(".", "foo.bar");
echo $first; // foo
This also works if you need the second (or third, etc.) element:
list($_, $second) = explode(".", "foo.bar");
echo $second; // bar
But that can get pretty clumsy.
Use current(), to get first position after explode:
$beforeDot = current(explode(".", $string));
Use array_shift() for this purpose :
$beforeDot = array_shift(explode(".", $string));
in php <= 5.3 you need to use
$beforeDot = explode(".", $string);
$beforeDot = $beforeDot[0];
2020 : Google brought me here for something similar.
Pairing 'explode' with 'implode' to populate a variable.
explode -> break the string into an array at the separator
implode -> get a string from that first array element into a variable
$str = "ABC.66778899";
$first = implode(explode('.', $str, -1));
Will give you 'ABC' as a string.
Adjust the limit argument in explode as per your string characteristics.
You can use the limit parameter in the explode function
explode($separator, $str, $limit)
$txt = 'the quick brown fox';
$explode = explode(' ', $txt, -substr_count($txt, ' '));
This will return an array with only one index that has the first word which is "the"
PHP Explode docs
Explanation:
If the limit parameter is negative, all components except the last
-limit are returned.
So to get only the first element despite the number of occurences of the substr you use -substr_count

Tricky php string matching

I have a string that looks like this:
[2005]
one
two
three
[2004]
six
What would be the smoothest was to get an array from it that would look like this:
array(
['2005'] => "one \n two \n three",
['2005'] => "six",
)
... or maybe even get the inner array sliced into lines array...
I tried doing it with preg_split, which worked but didn't give associative array keys so I didn't have the year numbers as keys.
Is there any cool way of doing this without iterating through all the lines ?
/(\[[0-9]{4}\])([^\[]*)/ will give you the date and whatever is after until the next one.
Use the groups to create your array: With preg_match_all() you get a $matches array where $matches[1] is the date and $matches[2] is the data following it.
Using Sylverdrag's regex as a guide:
<?php
$test = "[2005]
one
two
three
[2004]
six";
$r = "/(\[[0-9]{4}\])([^\[]*)/";
preg_match_all($r, $test, $m);
$output = array();
foreach ($m[1] as $key => $name)
{
$name = str_replace(array('[',']'), array('',''), $name);
$output[ $name ] = $m[2][$key];
}
print_r($output);
?>
Output (PHP 5.2.12):
Array
(
[2005] =>
one
two
three
[2004] =>
six
)
That's slightly more complex:
preg_match_all('/\[(\d+)\]\n((?:(?!\[).+\n?)+)/', $ini, $matches, PREG_SET_ORDER);
(Could be simplified with knowing the real format constraints.)

extracting multiple fields from a text file using php

what is the best way of extracting multiple (~40 values) from a text file using php?
the data is more or less like:
NAMEA valuea
NAMEB valueb
I'm looking for a proper* approach to extracting this data into a data-structure, because i will need to specify regexs for all of them (all 40).
did i make myself clear?
*meaning, the default/painful method would be for me to do:
$namea = extractfunction("regexa", $textfilevalue);
$nameb = extractfunction("regeb", $textfilevalue);
... 40 times!
The lines may not be in the same order, or be present in each file. Every NAMEA is text like: "Registration Number:", or "Applicant Name:" (ie, with spaces in what i was calling as NAMEA)
Response to the Col.
i'm looking for a sensible "way" of writing my code, so its readable, modifiable, builds an object/array thats easily callable, etc... "good coding style!" :)
#Adam - They do actually... and contain slashes as well...
#Alix - Freaking marvelous man! THat was GOOD! would you also happen to have any insights on how I can "truncate" the rsultant array by removing everything from "key_x" and beyond? Should i open that as a new question?
Here is my take at it:
somefile.txt:
NAMEA valuea
NAMEB valueb
PHP Code:
$file = file_get_contents('./somefile.txt');
$string = preg_replace('~^(.+?)\s+(.+?)$~m', '$1=$2', $file);
$string = str_replace(array("\r\n", "\r", "\n"), '&', $string);
$result = array();
parse_str($string, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
Output:
Array
(
[NAMEA] => valuea
[NAMEB] => valueb
)
You may also be able to further simplify this by using str_getcsv() on PHP 5.3+.
EDIT: My previous version fails for keys that have spaces like #Col. Shrapnel noticed. I didn't read the question with enough attention. A possible solution since you seem to be using keys that always have : appended is this:
$string = preg_replace('~^(.+?):\s+(.+?)$~m', '$1=$2', $file);
To remove everything from key_x to the end of the file you can do something like this:
$string = substr($string, 0, strpos($string, 'key_x'));
So the whole thing would look like this:
somefile.txt:
Registration Number: valuea
Applicant Name: valueb
PHP Code:
$file = file_get_contents('./somefile.txt');
$string = substr($file, 0, strpos($file, 'key_x'));
$string = preg_replace('~^(.+?):\s+(.+?)$~m', '$1=$2', $string);
$string = str_replace(array("\r\n", "\r", "\n"), '&', $string);
$result = array();
parse_str($string, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
Output:
Array
(
[Registration_Number] => valuea
[Applicant_Name] => valueb
)
as far as I get it you can use file() to get an array of strings and then parse these strings with some regexp.
if you add a = sign between names and values, you'll be ble to get the whole thing at once using parse_ini_file()
Assuming your keys (namea, nameb) never have spaces in them:
$contents = file('some_file.txt'); // read file as array
$data = array();
foreach($contents as $line) { // iterate over file
preg_match('/^([^\s]+)\s+(.*)/', $line, $matches); // pull out key and value into $matches
$key = $matches[1];
$value = $matches[2];
$data[$key] = $value; // store key/value pairs in $data array
}
var_dump($data); // what did we get?

Categories