separate a string from some specific words in php - php

I have a string called $metar
$metar = EICK 011300Z 10004KT 27/17 Q1018 TEMPO AT0800 20006KT 010V220 9999 SCT029
and this string could changed every an hour depending a dynamic file.
in basic, i want to separate the $metar to two strings, the separate point is "AT0800"
list($a, $b) = explode(' AT0800 ', $metar);
echo $b;
but the problem is the "AT0800" could change to "AT1200" or "AT1900" in the future, the only words are keep is the "AT", So how can i get the string $b which is after the word "ATxxxx" ? Thanks

Split the string with AT#### using a regex:
$metar_split = preg_split('/AT[0-9]{4}/', $metar);
The first half:
echo trim($metar_split[0]);
The second half (the one you're looking for):
$b = trim($metar_split[1]);
To get the AT#### portion:
preg_match('/AT[0-9]{4}/', $metar, $matches);
$metar_at = $matches[0];

If the position of ATxxxx in the string is always fixed (and the number of characters before it are also fixed), and xxxx always means 4 digits, then you could just go and use substr to select the desired segment of the string, as in:
$part1 = substr($metar, 0, 38);
$part2 = substr($metar, 46);
However, if you are looking at a varying lengths for the rest of the content, yet ATxxxx format is expected, you could have at it with a regular expression along the lines of:
([\w\s\/]+) AT[0-9]{4} ([\w\s\/]+)
This will grab out your two parts, which are seperated by the letters AT and exactly 4 digits. The [\w\s\/]+ part says: "grab me word characters (letters and numbers), white spaces and slash characters at least one, or any number more".

here you go, the answer is attached below:
list($a, $b) = explode('AT', $metar, 2);
//echo $b;
list($c, $d) = explode(' ', $b, 2);
//echo $d;

Related

How can I get number from a special string ? PHP

For example, 3 string are the following :
##7##
##563##
##120058##
How can I get those number like this :
echo first number is 7
echo second number is 563
echo third number is 120058
Thank you very much!
$numberAsString = trim($string, '##')
Is probably the easiest and fastest in this case. The output is still a string in this case, but in most cases that doesn't really matter. If it does in your case, you can use (int), (float) or the like to get it to the correct type.
Of course, regex would also be possible, e.g.:
$didMatch = preg_match('/#+([^#]+)#+/', $string, $matches);
Another possibility still is first extract the remaining part after the initial 2 # and then cast to a number, which seems to be always int in this case:
$number = (int)substr($string, 2);
Still another possibility would be to go by the count of the characters and just use substr like:
$numberAsString = substr($string, 2, -2);
Or you could be creative and use something like explode + implode + array functions:
$numberAsString = array_slice(explode('#', implode('', array_slice(explode('#', $string), 2))), 0, -2);
Of course, this last one is purely to show that it can be done in various ways, as it's very inefficient and impractical, but there are surely dozens of other ways.
In case you use this in a tight loop or somewhere where performance really matters, I would benchmark different possibilities - on a guess, I'd say that either the trim or the pure substring solution would be the fastest.
$str = "##563##";
preg_match("|\d+|", $str, $res);
print_r($res);
Just call the filter_var() function it will return the number only.
Whatever the input is, it will only filter the number for you!
filter_var("##120058##", FILTER_SANITIZE_NUMBER_INT) // return 120058
filter_var("*##20kkk", FILTER_SANITIZE_NUMBER_INT) // return 20

How to split characters with "-" character?

I generated a serial number with php, the length of this serial number is 16 characters, I want to split this serial number in 4 characters with dash(-) character, like this format xxxx-xxxx-xxxx-xxxx so I wrote this php code:
for ($d=0; $d<=3; $d++){
$tmp .= ($tmp ? "-" : null).substr($serial,$d,4);
}
so this loop will return a serial number with xxxx-xxxx-xxxx-xxxx format,
I want to know is there any better way or function in php?
I searched in internet I found sprintf and number_format but I don't know how can I use this function for this format !
I would use str_split() and implode():
$result = implode( '-', str_split( $serial, 4));
str_split() will break the string into an array, where each element has 4 characters. Then, implode() joins those array pieces together with a dash.
So, if we generate a random $serial with:
$serial = substr(md5(uniqid(rand(), true)), 0, 16);
We would get as output something similar to:
59e6-997f-8446-80a2
Try this :
$str = "xxxxxxxxxxxxxxxx";
echo substr(chunk_split($str, 4, '-'), 0, -1);
Output :
xxxx-xxxx-xxxx-xxxx
Ref: http://www.php.net/manual/en/function.chunk-split.php
str_split, fairly clear...
$hyphenated = implode( '-', str_split( $str, 4));
That is pretty clear, but it seems kind of wasteful to generate an array only to implode it. So I wondered if there was another way...
Faster with preg_replace?
I tried a regex, thinking that would eliminate the need for an intermediate array. After all, why have one problem, when you can have two!
$hyphenated = preg_replace('/(.{4})(?=.)/', '$1-', $str);
That little beastie looks for 4 characters, and as long they are followed by at least one more character, will insert a slash after them.
Trouble is, it turned out to be around 25% slower :(
chunk_split faster and with the same great minty taste!
Prasanth Bendra posted a pretty efficient answer which needs no intermediate array
$hyphenated=substr(chunk_split($str, 4, '-'), 0, -1); 
Result! This was at least 25% faster than using str_split measured on a 16 character input string, and just as clear as the str_split method.
You can try str_split() with an implode() such as:
$tmpArray = str_split($tmp, 4);
$serialNumber = implode('-', $tmpArray);

PHP - How to get the string between two specific characters

I got now a two sides that contains numbers and between two specific numbers there is a string that shows a group of numbers, Let's say we got this 123456789$numbers1234567 and I want to get the result of $numbers so how can I get it?
Thanks
If you know the two strings that it is sandwiched between then you can strip out the strings that you are looking for.
Not too elegant but this works:
$str1 = "123456789";
$str2 = "1234567";
$numberstr = "123456789";
$searchstring = "123456789".$numberstr."1234567";
$limit = 1;
$numbers = substr($searchstring, 0, strlen($searchstring) - strlen($str2)); // Remove the end of the string with length = $str2
$numbers = substr($numbers, strlen($numbers) - strlen($str1)); // Remove the most string from the beginning
print $numbers;
Output:
123456789
In summary, it removes the known string from the end, then the other known string from the beginning.
UPDATE: as per the comments, use two substrs to find the wanted string

PHP Using str_word_count with strsplit to form array after x words

I've got a large string that I want to put in an array after each 50 words. I thought about using strsplit to cut, but realised that wont take the words in to consideration, just split when it gets to x char.
I've read about str_word_count but can't work out how to put the two together.
What I've got at the moment is:
$outputArr = str_split($output, 250);
foreach($outputArr as $arOut){
echo $arOut;
echo "<br />";
}
But I want to substitute that to form each item of the array at 50 words instead of 250 characters.
Any help will be much appreciated.
Assuming that str_word_count is sufficient for your needs¹, you can simply call it with 1 as the second parameter and then use array_chunk to group the words in groups of 50:
$words = str_word_count($string, 1);
$chunks = array_chunk($words, 50);
You now have an array of arrays; to join every 50 words together and make it an array of strings you can use
foreach ($chunks as &$chunk) { // important: iterate by reference!
$chunk = implode(' ', $chunk);
}
¹ Most probably it is not. If you want to get what most humans consider acceptable results when processing written language you will have to use preg_split with some suitable regular expression instead.
There's another way:
<?php
$someBigString = <<<SAMPLE
This, actually, is a nice' old'er string, as they said, "divided and conquered".
SAMPLE;
// change this to whatever you need to:
$number_of_words = 7;
$arr = preg_split("#([a-z]+[a-z'-]*(?<!['-]))#i",
$someBigString, $number_of_words + 1, PREG_SPLIT_DELIM_CAPTURE);
$res = implode('', array_slice($arr, 0, $number_of_words * 2));
echo $res;
Demo.
I consider preg_split a better tool (than str_word_count) here. Not because the latter is inflexible (it is not: you can define what symbols can make up a word with its third param), but because preg_split will essentially stop processing the string after getting N items.
The trick, as quite common with this function, is to capture delimiters as well, then use them to reconstruct the string with the first N words (where N is given) AND punctuation marks saved.
(of course, the regex used in my example does not strictly comply to str_word_count locale-dependent behavior. But it still restricts the words to consist of alpha, ' and - symbols, with the latter two not at the beginning and the end of any word).

Validate measurements with PHP

I need to validate measurements entered into a form generated by PHP.
I intend to compare them to upper and lower control limits and decide if they fail or pass.
As a first step, I imagine a PHP function which accepts strings representing engineering measurements and converts them to pure numbers before the comparison.
At the moment I'm only expecting measurements of small voltages and currents, so strings like
'1.234uA', '2.34 nA', '39.9mV'. or '-1.003e-12'
will be converted to
1.234e-6, 2.34e-9, 3.99e-2 and -1.003e-12, respectively.
But the method should be generalisable to any measured quantity.
function convert($value) {
$units = array('p' => 'e-12',
'n' => 'e-9',
'u' => 'e-6',
'm' => 'e-3');
$unitstring = implode("", array_keys($units));
$matches = array();
$pattern = "/^(-?(?:\\d*\.\\d+)|(?:\\d+))\s*([$unitstring])([a-z])$/i";
$result = preg_match($pattern, $value, $matches);
if ($result)
$retval = $matches[1].$units[$matches[2]].$matches[3];
else
$retval = $value;
return $retval;
}
So to explain what the above does:
$units is an array to map unit-prefix to the exponent.
$unitstring conglomerates the units into a single string (in the example it would be 'pnum')
The regular expression will match an optional -, followed by either 0 or more digits, a period and 1 or more digits OR 1 or more digits, followed by one of the unit prefixes (only one) and then a single alphabetical character. There can be any amount of whitespace between the number and the units.
Because of the parethesis and the use of preg_match, the number section, the unit prefix, and the unit are all separately captured in the array $matches as elements 1, 2, and 3. (0 will contain the entire string)
$result will be 1 if it matched the regex, 0 otherwise.
$retval is constructed by just connecting the number, the exponent (based on the unit prefix from the array) and the units provided, or it will just be the passed in string (such as if you're given the -1.003e-12, it will be returned)
Of course you can tweak some things, but in general this is a good start. Hope it helps.
In your function
first you need to initialize values for units like -6 for u, -3 for m...etc
divide the string in Number and Unit(i.e micro(u),mili(m),etc).
and then say the entered no is NUM; and unit is UNIT..(char like u,m etc);
while(NUM>10)
{
NUM=NUM/10;
x++; //x is keeping track of the DOT.
}
UNIT=UNIT+x; //i.e UNIT is increased(for M,K,etc) or decreased(for u,m,etc)
echo NUM.e.UNIT;
May be it will do!
My own possibly simple-minded approach has been to use an array of patterns in preg_replace
function convert($value) {
$result = preg_replace($patterns, $replacements, $value);
return $result;
}
Where
$patterns = array('/p[av]/i', '/n[av]/i', '/u[av]/i', '/m[av]/i');
$replacements = array('e-12', 'e-9', 'e-6', 'e-3');
And it could be extended to higher prefixes, but it seems heavy-handed to keep adding increasingly complex regexes to the $patterns array.
Edit: The comparison, later, should interpret the return value as a real number.
I'm hoping someone can suggest something more elegant.

Categories