How to get a value from string after a specific substring? - php

My input string:
Yth. ErzaPay.com (DS008206). Sal:465.670, Dlm proses:0. Pemakaian hr
ini:126.885 Komisi:0 #*IDN1,IDN3 Open harga naik
How can I get the string value 465.670 ?

If this is a fairly strict format then you can use explode to get the value.
Other option it to use regex.
$temp = explode("Sal:",$str);
$sal = explode(",", $temp[1])[0];
echo $sal; //465.670
https://3v4l.org/Z6GfF

$string = "Yth. ErzaPay.com (DS008206). Sal:465.670, Dlm proses:0. Pemakaian hr ini:126.885 Komisi:0 #*IDN1,IDN3 Open harga naik";
$matches = [];
preg_match_all('/(\w+):([\.\d]+)/', $string, $matches);
// var_dump($matches);
$matches = [];
preg_match_all('/Sal:([\.\d]+)/', $string, $matches);
// var_dump($matches);
var_dump($matches[1][0]);

I prefer preg_match() for this task. It is cleanest to match the identifying substring, then reset the full string match with \K, then match 1 or more characters that are not a comma. Job done.
Using preg_match_all() to extract a single string makes no logical sense.
I prefer not to make successive explosions because it is generating arrays on the way to isolating a substring. In other words, it is simply indirect. If you are going to use explode() to hack a string into smaller chunks while searching for a solitary substring, use the third parameter of 2 so that php doesn't carry on looking for more delimiters to explode on.
strstr() with a true third parameter extracts the portion of a substring before a first encountered substring, so this can be used instead of a second explode() call.
I could go on list other whacky techniques, but at the end of the day, regex affords a direct and concise solution, so I would likely use preg_match() in my production code.
You were not clear about how your input strings may vary. I have only provided techniques suitable for your exact input.
Codes: (Demo)
$input = 'Yth. ErzaPay.com (DS008206). Sal:465.670, Dlm proses:0. Pemakaian hr ini:126.885 Komisi:0 #*IDN1,IDN3 Open harga naik';
echo preg_match('~Sal:\K[^,]+~', $input, $out) ? $out[0] : 'no match';
echo "\n---\n";
echo preg_replace('~^.*?Sal:|,.*?$~', '', $input);
echo "\n---\n";
echo strstr(explode('Sal:', $input, 2)[1], ',', true);
echo "\n---\n";
echo explode(',', explode('Sal:', $input, 2)[1], 2)[0];
echo "\n---\n";
if (($startPos = strpos($input, 'Sal:')) !== false && ($endPos = strpos($input, ',', $startPos)) !== false) {
$substrPos = $startPos + 4;
$substrLen = $endPos - $substrPos;
echo substr($input, $substrPos, $substrLen);
}
Output:
465.670
---
465.670
---
465.670
---
465.670
---
465.670

Related

Explode php string on X occurrence of a specific word

How do you select the content of a string based on a changing count?Each time the loop is run the count increments by 1 and the next portion of the string is required.
$mystring = 'This is my string. This string is a sample. This is a problem';
So if $i==1 then I want
echo $newstring // This is my string.
At $i==2 I want
echo $newstring // This string is a sample.
At $i==3 I want
echo $newstring // This is a problem.
I have looked at lots of reference pages on explode, substr, array_pop etc but I haven't seen a method that allows for the position of the trigger word to change based on an incrementing counter.
This could be answered with Explode a paragraph into sentences in PHP
foreach (preg_split('/[.?!]/',$mystring) as $sentence) {
echo $sentence;
}
Also you can access each element:
$matches = preg_split('/[.?!]/',$mystring);
echo $matches[0]; // This is my string
echo $matches[1]; // This string is a sample
echo $matches[2]; // This is a problem
If . is the part where you want to explode the string then you can use regular expression.
$line = 'This is my string. This string is a sample. This is a problem.';
preg_match("/([[:alpha:]|\s]+\.)/i", $line, $match);
echo $match[1];
Example
https://regex101.com/r/4SHAJj/1
I found a solution to this, and although it may not be the cleanest or best way, it does work.
$shippingData contains
Shipping (<div class="AdvancedShipperShippingMethodCombination"><p class="AdvancedShipperShippingMethod">Free Shipping <br />1 x IARP IA313200 Door Gasket</p> <p class="AdvancedShipperShippingMethod">Economy Delivery (1Kg) <br />1 x WIP69457. Whirlpool Part Number 481946669457</p></div>)';
Code used:
$shippingData = $order_result->fields['shipping_method'];
$matches = preg_split("/(AdvancedShipperShippingMethod\">)/", $shippingData);
$method = $matches[$n]; //$n is a count that increments with while/next loop
$method = substr($method, 0, strpos($method, "<br />"));
$method = "Shipping (".$method.")";
}

Remove all characters after last instance of particular character

How can I remove all the content in a string after the LAST occurance of a slash character / ?
For example, the string is:
http://localhost/new-123-rugby/competition.php?croncode=12345678
I want to remove all the content after the last / so that it just shows:
http://localhost/new-123-rugby/
But the content after the / could be of a variable length.
Please note, there could be any number of slashes in the URL. It needs to be able to remove content after the last slash. There could be more than shown in the example above.
you can try this
$url = "http://localhost/new-123-rugby/competition.php?croncode=12345678";
preg_match("/[^\/]+$/", $url, $matches);
$newUrl = str_replace($matches[0],'',$url);
echo $newUrl;
Solution #1, using substr() + strrpos():
$string = 'http://localhost/new-123-rugby/competition.php?croncode=12345678';
$pos = strrpos($string, '/');
if ($pos !== FALSE) {
echo(substr($string, 0, $pos + 1));
}
Function strrpos() finds the position of the last occurrence of / in the string, substr() extracts the required substring.
Drawback: if $string does not contain '/', strrpos() returns FALSE and substr() does not return what we want. Need to check the value returned by strrpos() first.
Solution #2, using explode() + implode():
$string = 'http://localhost/new-123-rugby/competition.php?croncode=12345678';
$array = explode('/', $string);
if (count($array) > 1) {
array_pop($array); // ignore the returned value, we don't need it
echo(implode('/', $array).'/'); // join the pieces back, add the last '/'
}
Alternatively, instead of array_pop($array) we can make the last component empty and there is no need to add an extra '/' at the end:
$string = 'http://localhost/new-123-rugby/competition.php?croncode=12345678';
$array = explode('/', $string);
if (count($array) > 1) {
$array[count($array) - 1] = ''; // empty the last component
echo(implode('/', $array)); // join the pieces back
}
Drawback (for both versions): if $string does not contain '/', explode() produces an array containing a single value and the rest of the code produces either '/' (the first piece of code) or an empty string (the second). Need to check the number of items in the array produced by explode().
Solution #3, using preg_replace():
$string = 'http://localhost/new-123-rugby/competition.php?croncode=12345678';
echo(preg_replace('#/[^/]*$#', '/', $string));
Drawbacks: none. It works well when both when $string contains '/' and it does not contain '/' (it does not modify $string in this case).
NOTA:
The question was edited so that the original answer (below the edit), doesn't match the requirements from OP. It wasn't marked as an edit from OP.
EDIT:
Updated my answer so it now matches the requirements of OP:
(Now it works with as many slashes as you want)
Will also work using
http://localhost/new-123-rugby////////competition.php?croncode=12345678
<?php
$url = "http://localhost/new-123-rugby/competition.php?croncode=12345678";
echo dirname($url) . "/";
?>
Output:
http://localhost/new-123-rugby/
Original answer:
This should work for you:
<?php
$string = "http://localhost/new-123-rugby/competition.php?croncode=12345678";
echo $string = substr($string, 0, strpos(strrev($string), "/")-2);
?>
Output:
http://localhost/new-123-rugby/
Demo: http://ideone.com/0R9QUG

How do I get the last part of a string in PHP

I have many strings that follow the same convention:
this.is.a.sample
this.is.another.sample.of.it
this.too
What i want to do is isolate the last part. So i want "sample", or "it", or "too".
What is the most efficient way for this to happen. Obviously there are many ways to do this, but which way is best that uses the least resources (CPU and RAM).
$string = "this.is.another.sample.of.it";
$contents = explode('.', $string);
echo end($contents); // displays 'it'
I realise this question is from 2012, but the answers here are all inefficient. There are string functions built into PHP to do this, rather than having to traverse the string and turn it into an array, and then pick the last index, which is a lot of work to do something quite simple.
The following code gets the last occurrence of a string within a string:
strrchr($string, '.'); // Last occurrence of '.' within a string
We can use this in conjunction with substr, which essentially chops a string up based on a position.
$string = 'this.is.a.sample';
$last_section = substr($string, (strrchr($string, '-') + 1));
echo $last_section; // 'sample'
Note the +1 on the strrchr result; this is because strrchr returns the index of the string within the string (starting at position 0), so the true 'position' is always 1 character on.
http://us3.php.net/strpos
$haystack = "this.is.another.sample.of.it";
$needle = "sample";
$string = substr( $haystack, strpos( $haystack, $needle ), strlen( $needle ) );
Just do:
$string = "this.is.another.sample.of.it";
$parts = explode('.', $string);
$last = array_pop(parts);
$new_string = explode(".", "this.is.sparta");
$last_part = $new_string[count($new_string)-1];
echo $last_part; // prints "sparta".
$string = "this.is.another.sample.of.it";
$result = explode('.', $string); // using explode function
print_r($result); // whole Array
Will give you
result[0]=>this;
result[1]=>is;
result[2]=>another;
result[3]=>sample;
result[4]=>of;
result[5]=>it;
Display any one you want (ex. echo result[5];)

mb_eregi_replace multiple matches get them

$string = 'test check one two test3';
$result = mb_eregi_replace ( 'test|test2|test3' , '<$1>' ,$string ,'i');
echo $result;
This should deliver: <test> check one two <test3>
Is it possible to get, that test and test3 was found, without using another match function ?
You can use preg_replace_callback instead:
$string = 'test check one two test3';
$matches = array();
$result = preg_replace_callback('/test|test2|test3/i' , function($match) use ($matches) {
$matches[] = $match;
return '<'.$match[0].'>';
}, $string);
echo $result;
Here preg_replace_callback will call the passed callback function for each match of the pattern (note that its syntax differs from POSIX). In this case the callback function is an anonymous function that adds the match to the $matches array and returns the substitution string that the matches are to be replaced by.
Another approach would be to use preg_split to split the string at the matched delimiters while also capturing the delimiters:
$parts = preg_split('/test|test2|test3/i', $string, null, PREG_SPLIT_DELIM_CAPTURE);
The result is an array of alternating non-matching and matching parts.
As far as I know, eregi is deprecated.
You could do something like this:
<?php
$str = 'test check one two test3';
$to_match = array("test", "test2", "test3");
$rep = array();
foreach($to_match as $val){
$rep[$val] = "<$val>";
}
echo strtr($str, $rep);
?>
This too allows you to easily add more strings to replace.
Hi following function used to found the any word from string
<?php
function searchword($string, $words)
{
$matchFound = count($words);// use tha no of word you want to search
$tempMatch = 0;
foreach ( $words as $word )
{
preg_match('/'.$word.'/',$string,$matches);
//print_r($matches);
if(!empty($matches))
{
$tempMatch++;
}
}
if($tempMatch==$matchFound)
{
return "found";
}
else
{
return "notFound";
}
}
$string = "test check one two test3";
/*** an array of words to highlight ***/
$words = array('test', 'test3');
$string = searchword($string, $words);
echo $string;
?>
If your string is utf-8, you could use preg_replace instead
$string = 'test check one two test3';
$result = preg_replace('/(test3)|(test2)|(test)/ui' , '<$1>' ,$string);
echo $result;
Oviously with this kind of data to match the result will be suboptimal
<test> check one two <test>3
You'll need a longer approach than a direct search and replace with regular expressions (surely if your patterns are prefixes of other patterns)
To begin with, the code you want to enhance does not seem to comply with its initial purpose (not at least in my computer). You can try something like this:
$string = 'test check one two test3';
$result = mb_eregi_replace('(test|test2|test3)', '<\1>', $string);
echo $result;
I've removed the i flag (which of course makes little sense here). Still, you'd still need to make the expression greedy.
As for the original question, here's a little proof of concept:
function replace($match){
$GLOBALS['matches'][] = $match;
return "<$match>";
}
$string = 'test check one two test3';
$matches = array();
$result = mb_eregi_replace('(test|test2|test3)', 'replace(\'\1\')', $string, 'e');
var_dump($result, $matches);
Please note this code is horrible and potentially insecure. I'd honestly go with the preg_replace_callback() solution proposed by Gumbo.

PHP: Best way to extract text within parenthesis?

What's the best/most efficient way to extract text set between parenthesis? Say I wanted to get the string "text" from the string "ignore everything except this (text)" in the most efficient manner possible.
So far, the best I've come up with is this:
$fullString = "ignore everything except this (text)";
$start = strpos('(', $fullString);
$end = strlen($fullString) - strpos(')', $fullString);
$shortString = substr($fullString, $start, $end);
Is there a better way to do this? I know in general using regex tends to be less efficient, but unless I can reduce the number of function calls, perhaps this would be the best approach? Thoughts?
i'd just do a regex and get it over with. unless you are doing enough iterations that it becomes a huge performance issue, it's just easier to code (and understand when you look back on it)
$text = 'ignore everything except this (text)';
preg_match('#\((.*?)\)#', $text, $match);
print $match[1];
So, actually, the code you posted doesn't work: substr()'s parameters are $string, $start and $length, and strpos()'s parameters are $haystack, $needle. Slightly modified:
$str = "ignore everything except this (text)";
$start = strpos($str, '(');
$end = strpos($str, ')', $start + 1);
$length = $end - $start;
$result = substr($str, $start + 1, $length - 1);
Some subtleties: I used $start + 1 in the offset parameter in order to help PHP out while doing the strpos() search on the second parenthesis; we increment $start one and reduce $length to exclude the parentheses from the match.
Also, there's no error checking in this code: you'll want to make sure $start and $end do not === false before performing the substr.
As for using strpos/substr versus regex; performance-wise, this code will beat a regular expression hands down. It's a little wordier though. I eat and breathe strpos/substr, so I don't mind this too much, but someone else may prefer the compactness of a regex.
Use a regular expression:
if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
$text = $match[1];
i think this is the fastest way to get the words between the first parenthesis in a string.
$string = 'ignore everything except this (text)';
$string = explode(')', (explode('(', $string)[1]))[0];
echo $string;
The already posted regex solutions - \((.*?)\) and \(([^\)]+)\) - do not return the innermost strings between an open and close brackets. If a string is Text (abc(xyz 123) they both return a (abc(xyz 123) as a whole match, and not (xyz 123).
The pattern that matches substrings (use with preg_match to fetch the first and preg_match_all to fetch all occurrences) in parentheses without other open and close parentheses in between is, if the match should include parentheses:
\([^()]*\)
Or, you want to get values without parentheses:
\(([^()]*)\) // get Group 1 values after a successful call to preg_match_all, see code below
\(\K[^()]*(?=\)) // this and the one below get the values without parentheses as whole matches
(?<=\()[^()]*(?=\)) // less efficient, not recommended
Replace * with + if there must be at least 1 char between ( and ).
Details:
\( - an opening round bracket (must be escaped to denote a literal parenthesis as it is used outside a character class)
[^()]* - zero or more characters other than ( and ) (note these ( and ) do not have to be escaped inside a character class as inside it, ( and ) cannot be used to specify a grouping and are treated as literal parentheses)
\) - a closing round bracket (must be escaped to denote a literal parenthesis as it is used outside a character class).
The \(\K part in an alternative regex matches ( and omits from the match value (with the \K match reset operator). (?<=\() is a positive lookbehind that requires a ( to appear immediately to the left of the current location, but the ( is not added to the match value since lookbehind (lookaround) patterns are not consuming. (?=\() is a positive lookahead that requires a ) char to appear immediately to the right of the current location.
PHP code:
$fullString = 'ignore everything except this (text) and (that (text here))';
if (preg_match_all('~\(([^()]*)\)~', $fullString, $matches)) {
print_r($matches[0]); // Get whole match values
print_r($matches[1]); // Get Group 1 values
}
Output:
Array ( [0] => (text) [1] => (text here) )
Array ( [0] => text [1] => text here )
This is a sample code to extract all the text between '[' and ']' and store it 2 separate arrays(ie text inside parentheses in one array and text outside parentheses in another array)
function extract_text($string)
{
$text_outside=array();
$text_inside=array();
$t="";
for($i=0;$i<strlen($string);$i++)
{
if($string[$i]=='[')
{
$text_outside[]=$t;
$t="";
$t1="";
$i++;
while($string[$i]!=']')
{
$t1.=$string[$i];
$i++;
}
$text_inside[] = $t1;
}
else {
if($string[$i]!=']')
$t.=$string[$i];
else {
continue;
}
}
}
if($t!="")
$text_outside[]=$t;
var_dump($text_outside);
echo "\n\n";
var_dump($text_inside);
}
Output:
extract_text("hello how are you?");
will produce:
array(1) {
[0]=>
string(18) "hello how are you?"
}
array(0) {
}
extract_text("hello [http://www.google.com/test.mp3] how are you?");
will produce
array(2) {
[0]=>
string(6) "hello "
[1]=>
string(13) " how are you?"
}
array(1) {
[0]=>
string(30) "http://www.google.com/test.mp3"
}
This function may be useful.
public static function getStringBetween($str,$from,$to, $withFromAndTo = false)
{
$sub = substr($str, strpos($str,$from)+strlen($from),strlen($str));
if ($withFromAndTo)
return $from . substr($sub,0, strrpos($sub,$to)) . $to;
else
return substr($sub,0, strrpos($sub,$to));
}
$inputString = "ignore everything except this (text)";
$outputString = getStringBetween($inputString, '(', ')'));
echo $outputString;
//output will be test
$outputString = getStringBetween($inputString, '(', ')', true));
echo $outputString;
//output will be (test)
strpos() => which is used to find the position of first occurance in a string.
strrpos() => which is used to find the position of first occurance in a string.
function getStringsBetween($str, $start='[', $end=']', $with_from_to=true){
$arr = [];
$last_pos = 0;
$last_pos = strpos($str, $start, $last_pos);
while ($last_pos !== false) {
$t = strpos($str, $end, $last_pos);
$arr[] = ($with_from_to ? $start : '').substr($str, $last_pos + 1, $t - $last_pos - 1).($with_from_to ? $end : '');
$last_pos = strpos($str, $start, $last_pos+1);
}
return $arr; }
this is a little improvement to the previous answer that will return all patterns in array form:
getStringsBetween('[T]his[] is [test] string [pattern]') will return:

Categories