How do I get the complete line from a position gotten by strpos()?
Here is my code:
//$route_route sample: NAXOP UZ45 VIKIK
$route_waypoint = explode(" ", $route_route);
$file = "components/airways.txt";
$contents = file_get_contents($file);
foreach ($route_waypoint as $waypoint) {
//$waypoint sample: NAXOP
$pos = strpos($contents, $waypoint);
if ($pos === false) {
continue;
} else {
$line = fgets($contents, $pos); // Here is my problem
//line sample: MES,W714,005,NAXOP,38.804139,30.546833,149,000, ,L
list($fix, $lat, $lon, $sample_data1, $sample_data2) = explode(',', $line);
echo "$fix, $lat, $lon";
}
}
The main objective is localize "NAXOP", read his complete line, and echo some data. Any kind of help is welcome!
DISCLAIMER: if VIKIK comes before NAXOP in $contents. VIKIK Will not be found, if there are multiple occurrences of NAXOP || UZ45 || VIKIK only the first of each occurrence will be found.
$len = strlen($contents);
$pos = 0;
foreach ($route_waypoint as $waypoint) {
$pos = strpos($contents, $waypoint, $pos);
if ($pos === false) {
continue;
}
else {
// Here is the critical section for matching the entire line:
// First look backwards from where $waypoint was found for the
// beginning of the line
$startOfLine = strrpos($contents, "\n", ($pos - $len));
// Next look forwards from $waypoint to find the end of the line
$endOfLine = strpos($contents, "\n", $pos);
// we already have the file in memory, just read from that,
$line = substr($contents, $startOfLine, ($endOfLine - $startOfLine));
list($fix, $lat, $lon, $sample_data1, $sample_data2)
= explode(',', trim($line));
echo "$fix, $lat, $lon";
// IDK if you want to match the same line twice or not.
$pos = $endOfLine;
}
}
Here is a better program.
<?php
$str = "NAXOP UZ45 VIKIK";
$regex = "/" . preg_replace("/ /", "|", $str) . "/";
$fp = fopen("test.dat", "r");
while ($line = fgets($fp)) {
if (preg_match($regex, $line)) {
echo $line;
}
}
fclose($fp);
Here is test.dat
NAXOP
UZ45
VIKIK
UZ45 VIKIK
NAXOP
SILLYSTRING
Here is the output
NAXOP
UZ45
VIKIK
UZ45 VIKIK
NAXOP
I've used this library in soo many programs.. check it out I think it'll solve exactly the problem you are having. It works exactly like it says..
e.g
between ('#', '.', 'biohazard#online.ge');
//returns 'online'
//from the first occurrence of '#'
src: http://php.net/manual/en/function.substr.php
<?php
function after ($this, $inthat)
{
if (!is_bool(strpos($inthat, $this)))
return substr($inthat, strpos($inthat,$this)+strlen($this));
};
function after_last ($this, $inthat)
{
if (!is_bool(strrevpos($inthat, $this)))
return substr($inthat, strrevpos($inthat, $this)+strlen($this));
};
function before ($this, $inthat)
{
return substr($inthat, 0, strpos($inthat, $this));
};
function before_last ($this, $inthat)
{
return substr($inthat, 0, strrevpos($inthat, $this));
};
function between ($this, $that, $inthat)
{
return before ($that, after($this, $inthat));
};
function between_last ($this, $that, $inthat)
{
return after_last($this, before_last($that, $inthat));
};
// use strrevpos function in case your php version does not include it
function strrevpos($instr, $needle)
{
$rev_pos = strpos (strrev($instr), strrev($needle));
if ($rev_pos===false) return false;
else return strlen($instr) - $rev_pos - strlen($needle);
};
?>
Related
$t = ABCDEFPN03KSASDEID;
$r = stristr($t, 'PN03', true);
My Value is $r = ABCDEF
and in if condition while i plan to seperate it throws output wrong
But i want output $s = PNO3KSASDEID like this
My code:
(I used variable as my own)
$r = stristr($t, 'PN03', true);
if( ($s = substr($t, 'PNO3', false)) == true) {
$s = stristr($t, 'PNO3', false);
print_r($s);
}
output: PN03KSASDEID is needed.
Please suggest me solution.
Get in the habit of encapsulating your behaviours in reusable functions
function str_split_term($string, $term) {
$pos = strpos($string, $term);
if ($pos === false)
return $string;
else
return substr($string, $pos);
}
Your use case
echo str_split_term('ABCDEFPN03KSASDEID', 'PN03'); // PN03KSASDEID
If the term is not found in the string, the string will output unaltered
echo str_split_term('ABCDEFPN03KSASDEID', 'ZZZ'); // ABCDEFPN03KSASDEID
PHP7
If you're are using a current version of PHP, I suggest you add type hints to the function
function str_split_term(string $string, string $term): string {
$pos = strpos($string, $term);
if ($pos === false)
return $string;
else
return substr($string, $pos);
}
I have an uri and want to get an array of parts starting with full uri descent until I have only the first uri segment as part. I also have domain but the segments get stitched starting from the end back.
String 'a/b/c' to array('a/b/c', 'a/b', 'a')
String 'test.domain.com' to array('test.domain.com', 'domain.com', 'com')
Based on my initial method and the second method from the answers and a third method I like to know which one is the quickest and maybe there is a fourth method even better...
Method 1:
function explode_special($delimiter, $string, $reverse = false)
{
if (strpos($string, $delimiter) === false) return array($string);
$segments = explode($delimiter, $string);
if ( ! $reverse)
{
array_walk($segments, function($v, $k, $d) use(&$segments, &$delimiter) {
$d[$k] = implode($delimiter, array_slice($segments, 0, (count($segments) - $k)));
}, &$parts);
}
else
{
array_walk($segments, function($v, $k, $d) use(&$segments, &$delimiter) {
$d[$k] = implode($delimiter, array_slice($segments, $k));
}, &$parts);
}
return $parts;
}
Method 2:
function explode_special($delimiter, $string, $reverse = false)
{
if (strpos($string, $delimiter) === false) return array($string);
$segments = explode($delimiter, $string);
$parts = array();
while ($segments)
{
$parts[] = implode($delimiter, $segments);
if ($reverse)
{
array_shift($segments);
}
else
{
array_pop($segments);
}
}
return $parts;
}
Method 3:
function explode_special($delimiter, $string, $reverse = false)
{
if (strpos($string, $delimiter) === false) return array($string);
$parts = array($string);
for ($i = substr_count($string, $delimiter); $i > 0; $i--)
{
$parts[] = $string = $reverse
// ? trim(strstr($string, $delimiter), $delimiter)
? substr($string, strpos($string, $delimiter) + 1)
: substr($string, 0, strrpos($string, $delimiter));
}
return $parts;
}
Output:
// explode_special('/', 'a/b/c') = array('a/b/c', 'a/b', 'c');
// explode_special('.', 'test.domain.com', true) =
// array('test.domain.com', 'domain.com', 'com');
function multisplit($delim,$str) {
$parts = explode($delim,$str);
$arr = Array();
while($parts) {
$arr[] = implode($delim,$parts);
array_pop($parts);
}
return $arr;
}
With that function, you can just call multisplit("/","a/b/c"); and it will return ['a/b/c','a/b','a']. Similarly, call multisplit(".","test.domain.com"); and get ['test.domain.com','test.domain','test'].
I came up with the following
<?php
header("Content-type: text/plain"); //For display purposes only
/**
* Returns an array of strings with diminishing elements of $string according to $delimiter
*
* #param string $string The string
* #param string $delimiter The delimiter
*
* #return string[] Array of strings
*/
function degrading_split($string, $delimiter) {
$exploded = explode($delimiter, $string); //Array version of the string
$result = array(); //Initialize result array
foreach ($exploded as $key => $value) { //Iterate the array
$result[] = implode( #Implode...
$delimiter, #Using the original delimiter
array_slice($exploded, $key) #The complete $exploded array starting from the current $key
);
}
return $result;
}
print_r(degrading_split("a/b/c/d", "/"));
What you think about this with regex
function splitString($string,$delim) {
$arr = array();
preg_match_all('~['.$delim.']~U',$string,$delimCounter);
$arr[] = $string;
for ($i = 0;$i<count($delimCounter[0]);$i++) {
$string = $arr[] = preg_replace('~^[^.]*['.$delim.']~',"",$string);
}
return $arr;
}
I need to remove all characters from any string before the occurrence of this inside the string:
"www/audio"
Not sure how I can do this.
You can use strstr to do this.
echo strstr($str, 'www/audio');
Considering
$string="We have www/audio path where the audio files are stored"; //Considering the string like this
Either you can use
strstr($string, 'www/audio');
Or
$expStr=explode("www/audio",$string);
$resultString="www/audio".$expStr[1];
I use this functions
function strright($str, $separator) {
if (intval($separator)) {
return substr($str, -$separator);
} elseif ($separator === 0) {
return $str;
} else {
$strpos = strpos($str, $separator);
if ($strpos === false) {
return $str;
} else {
return substr($str, -$strpos + 1);
}
}
}
function strleft($str, $separator) {
if (intval($separator)) {
return substr($str, 0, $separator);
} elseif ($separator === 0) {
return $str;
} else {
$strpos = strpos($str, $separator);
if ($strpos === false) {
return $str;
} else {
return substr($str, 0, $strpos);
}
}
}
You can use substring and strpos to accomplish this goal.
You could also use a regular expression to pattern match only what you want. Your mileage may vary on which of these approaches makes more sense.
How can i define multiple needles and still perform the same actions below. Im trying to define extra keywords such as numbers, numerals, etc... as of now i have to create a duplicate if loop with the minor keyword change.
if (stripos($data, 'digits') !== false) {
$arr = explode('+', $data);
for ($i = 1; $i < count($arr); $i += 2) {
$arr[$i] = preg_replace('/\d/', '', $arr[$i]);
}
$data = implode('+', $arr);
}
Create a function that loops through an array?
function check_matches ($data, $array_of_needles)
{
foreach ($array_of_needles as $needle)
{
if (stripos($data, $needle)!==FALSE)
{
return true;
}
}
return false;
}
if (check_matches($data, $array_of_needles))
{
//do the rest of your stuff
}
--edit added semicolon
function strposa($haystack, $needles=array(), $offset=0) {
$chr = array();
foreach($needles as $needle) {
$res = strpos($haystack, $needle, $offset);
if ($res !== false) $chr[$needle] = $res;
}
if(empty($chr)) return false;
return min($chr);
}
Usage:
$array = array('1','2','3','etc');
if (strposa($data, $array)) {
$arr = explode('+', $data);
for ($i = 1; $i < count($arr); $i += 2) {
$arr[$i] = preg_replace('/\d/', '', $arr[$i]);
}
$data = implode('+', $arr);
} else {
echo 'false';
}
function taken from https://stackoverflow.com/a/9220624/1018682
Though the previous answers are correct, but I'd like to add all the possible combinations, like you can pass the needle as array or string or integer.
To do that, you can use the following snippet.
function strposAll($haystack, $needles){
if(!is_array($needle)) $needles = array($needles); // if the $needle is not an array, then put it in an array
foreach($needles as $needle)
if( strpos($haystack, $needle) !== False ) return true;
return false;
}
You can now use the second parameter as array or string or integer, whatever you want.
I have a php string containing the serialization of a javascript object :
$string = '{fu:"bar",baz:["bat"]}';
The actual string is far more complicated, of course, but still well-formed javascript. This is not standard JSON, so json_decode fails. Do you know any php library that would parse this string and return a php associative array ?
This sounded like a fun challenge, so I coded up a tiny parser :D
class JsParserException extends Exception {}
function parse_jsobj($str, &$data) {
$str = trim($str);
if(strlen($str) < 1) return;
if($str{0} != '{') {
throw new JsParserException('The given string is not a JS object');
}
$str = substr($str, 1);
/* While we have data, and it's not the end of this dict (the comma is needed for nested dicts) */
while(strlen($str) && $str{0} != '}' && $str{0} != ',') {
/* find the key */
if($str{0} == "'" || $str{0} == '"') {
/* quoted key */
list($str, $key) = parse_jsdata($str, ':');
} else {
$match = null;
/* unquoted key */
if(!preg_match('/^\s*[a-zA-z_][a-zA-Z_\d]*\s*:/', $str, $match)) {
throw new JsParserException('Invalid key ("'.$str.'")');
}
$key = $match[0];
$str = substr($str, strlen($key));
$key = trim(substr($key, 0, -1)); /* discard the ':' */
}
list($str, $data[$key]) = parse_jsdata($str, '}');
}
"Finshed dict. Str: '$str'\n";
return substr($str, 1);
}
function comma_or_term_pos($str, $term) {
$cpos = strpos($str, ',');
$tpos = strpos($str, $term);
if($cpos === false && $tpos === false) {
throw new JsParserException('unterminated dict or array');
} else if($cpos === false) {
return $tpos;
} else if($tpos === false) {
return $cpos;
}
return min($tpos, $cpos);
}
function parse_jsdata($str, $term="}") {
$str = trim($str);
if(is_numeric($str{0}."0")) {
/* a number (int or float) */
$newpos = comma_or_term_pos($str, $term);
$num = trim(substr($str, 0, $newpos));
$str = substr($str, $newpos+1); /* discard num and comma */
if(!is_numeric($num)) {
throw new JsParserException('OOPSIE while parsing number: "'.$num.'"');
}
return array(trim($str), $num+0);
} else if($str{0} == '"' || $str{0} == "'") {
/* string */
$q = $str{0};
$offset = 1;
do {
$pos = strpos($str, $q, $offset);
$offset = $pos;
} while($str{$pos-1} == '\\'); /* find un-escaped quote */
$data = substr($str, 1, $pos-1);
$str = substr($str, $pos);
$pos = comma_or_term_pos($str, $term);
$str = substr($str, $pos+1);
return array(trim($str), $data);
} else if($str{0} == '{') {
/* dict */
$data = array();
$str = parse_jsobj($str, $data);
return array($str, $data);
} else if($str{0} == '[') {
/* array */
$arr = array();
$str = substr($str, 1);
while(strlen($str) && $str{0} != $term && $str{0} != ',') {
$val = null;
list($str, $val) = parse_jsdata($str, ']');
$arr[] = $val;
$str = trim($str);
}
$str = trim(substr($str, 1));
return array($str, $arr);
} else if(stripos($str, 'true') === 0) {
/* true */
$pos = comma_or_term_pos($str, $term);
$str = substr($str, $pos+1); /* discard terminator */
return array(trim($str), true);
} else if(stripos($str, 'false') === 0) {
/* false */
$pos = comma_or_term_pos($str, $term);
$str = substr($str, $pos+1); /* discard terminator */
return array(trim($str), false);
} else if(stripos($str, 'null') === 0) {
/* null */
$pos = comma_or_term_pos($str, $term);
$str = substr($str, $pos+1); /* discard terminator */
return array(trim($str), null);
} else if(strpos($str, 'undefined') === 0) {
/* null */
$pos = comma_or_term_pos($str, $term);
$str = substr($str, $pos+1); /* discard terminator */
return array(trim($str), null);
} else {
throw new JsParserException('Cannot figure out how to parse "'.$str.'" (term is '.$term.')');
}
}
Usage:
$data = '{fu:"bar",baz:["bat"]}';
$parsed = array();
parse_jsobj($data, $parsed);
var_export($parsed);
Gives:
array (
'fu' => 'bar',
'baz' =>
array (
0 => 'bat',
),
)
Tested with these strings:
'{fu:"bar",baz:["bat"]}',
'{rec:{rec:{rec:false}}}',
'{foo:[1,2,[3,4]]}',
'{fu:{fu:"bar"},bar:{fu:"bar"}}',
'{"quoted key":[1,2,3]}',
'{und:undefined,"baz":[1,2,"3"]}',
'{arr:["a","b"],"baz":"foo","gar":{"faz":false,t:"2"},f:false}',
Pear Services_JSON will parse that string (tested version 1.31). But given that that is a JSON parser and that this isn't valid JSON you have no guarantee that future versions will still work.
I found out that the Yii-framework's CJSON::decode() function handles Javascript objects as well.
If you're not using Yii, you should be able to just use the source code
thank luttkens
the CJON::decode() class of the Yii-framework works perfectly !
require_once ($_SERVER['DOCUMENT_ROOT']."/phplib/CJSON.php");
$json = new CJSON();
$data = $json->decode('{ url : "/jslib/maps/marker/marker_red.png", height : 34, width : 20, anchorIcon : [5,25.5], anchorText : [0,2], }', true);
print_r( $data );
result :
Array
(
[url] => /jslib/maps/marker/marker_red.png
[height] => 34
[width] => 20
[anchorIcon] => Array
(
[0] => 5
[1] => 25.5
)
[anchorText] => Array
(
[0] => 0
[1] => 2
)
)
What about that library?
http://timwhitlock.info/tag/jparser/
I haven't tried it yet.