I'm trying to scrape a products price from a page, however unfortunately it's not in a nice clean div so I'm having to clear all the other junk.
Note: I have looked at several examples however they all assume you only have nice organised numbers in your variable, not raw HTML stuffed on the end.
An example of the string my variable may hold:
$2.87 <span>10% Off Sale</span>
I've played about with substr and sttrpos, read the manual and still can't figure it out on my own.
I want to just cut the string two digits after the first decimal place is found... No doubt it's extremely simple when you know how!
What I want to end up with:
$2.87
An example of the mess I've got myself into trying:
$whatIWant = substr($data, strrpos($data, ".") + 2);
Thanks in advance,
Try this solution:
<?php
$string = "$2.87 <span>10% Off Sale</span>";
$matches = array();
preg_match('/(\$\d+\.\d{2})/', $string, $matches);
var_dump($matches);
Output:
array(2) {
[0]=>
string(5) "$2.87"
[1]=>
string(5) "$2.87"
}
For more info (why result is array etc.) you should check PHP manual on preg_match() function: link
The below should grab the matches for you;
$pattern = '/(\$\d+\.\d{2})/';
$string = '$2.87 <span>10% Off Sale</span>';
$matches = array();
preg_match($pattern, $string, $matches);
Outputs:
Array ( [0] => $2.87 [1] => $2.87 )
There is def better way to do this. For a start, assuming the html structure that you have above will always be the same, you could do something like:
$var = "$85.25 <span>10% Off Sale</span>";
$spl = explode("<", $var);
echo $spl[0];
Related
I'm working with a string containing parameters, separated by some special characters in PHP with preg_match
An example could be like this one, which has four parameters.
1stparm?#?1111?#?2ndParm?#?2222?#?3rdParm?#?3333?#?4thparm?#?444?#?
Each parameter name is followed by ?#?, and its value is right next to it, ending with ?#? (note: values can be strings or numbers, and even special characters)
I've probably overcomplicated my regex, which works in SOME cases, but not if I search for the last parameter in the string..
This example returns 2222 as the correct value (in group 1) for 2ndParm
(?:.*)2ndParm\?#\?(.*?)\?#\?(?=.)(.*)
but it fails if 2ndParm is the last one in the string as in the following example:
1stparm?#?1111?#?2ndParm?#?2222?#?
I'd also appreciate help in just returning one group with my result.. i havent been able to do so, but since I always get the one I'm interested in group 1, I can get it easily anyway.
Without regex:
$str ='1stparm?#?1111?#?2ndParm?#?2222?#?3rdParm?#?3333?#?4thparm?#?444?#?';
$keyval = explode('?#?', trim($str, '?#'));
$result = [];
foreach($keyval as $item) {
[$key, $result[$key]] = explode('?#?', $item);
}
print_r($result);
demo
You don't need to use a regex for everything, and you should have a serious talk with whoever invented this horrid format about the fact that JSON, YAML, TOML, XML, etc exist.
function bizarre_unserialize($in) {
$tmp = explode('?#?', $in);
$tmp = array_filter($tmp); // remove empty
$tmp = array_map(
function($a) { return explode('?#?', $a); },
$tmp
);
// rearrange to key-value
return array_combine(array_column($tmp, 0), array_column($tmp, 1));
}
$input = '1stparm?#?1111?#?2ndParm?#?2222?#?3rdParm?#?3333?#?4thparm?#?444?#?';
var_dump(
bizarre_unserialize($input)
);
Output:
array(4) {
["1stparm"]=>
string(4) "1111"
["2ndParm"]=>
string(4) "2222"
["3rdParm"]=>
string(4) "3333"
["4thparm"]=>
string(3) "444"
}
You can use
(?P<key>.+?)
\Q?#?\E
(?P<value>.+?)
\Q?#?\E
in verbose mode, see a demo on regex101.com.
The \Q...\E construct disables the ? and # "super-powers" (no need to escape them here).
In PHP this could be
<?php
$string = "1stparm?#?1111?#?2ndParm?#?2222?#?3rdParm?#?3333?#?4thparm?#?444?#?";
$regex = "~(?P<key>.+?)\Q?#?\E(?P<value>.+?)\Q?#?\E~";
preg_match_all($regex, $string, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
echo $match["key"] . " = " . $match["value"] . "\n";
}
?>
Which yields
1stparm = 1111
2ndParm = 2222
3rdParm = 3333
4thparm = 444
Or shorter:
$result = array_map(
function($x) {return array($x["key"] => $x["value"]);}, $matches);
print_r($result);
In the database I'm working on there's a string like this
1-Test Response|9-DNC|
This can have up to 9 pipe delimited items.
What I'm looking for advice on is the best possible way to take this string and turn it into an array with the number as the key and the string as the value.
I really suck with Regex. Can someone point me in the right direction?
Since it's not your fault you have the DB structured this way, please accept my sincere condolences. It must be hell working with this. Meh.
Now, to the point. You do not need regex to work with this string. If you have a problem and you want to solve it with regex, you have two problems.
Instead, use explode().
$testString = "1-Test Response|9-DNC|";
$result = [];
$explodedByPipeString = explode("|", $testString);
foreach($explodedByPipeString as $k => $v)
{
$explodedByDashString = explode("-", $v);
if(is_numeric($explodedByDashString[0]))
{
$result[$explodedByDashString[0]] = $explodedByDashString[1];
}
}
var_dump($result);
This gives
array(2) {
[1]=>
string(13) "Test Response"
[9]=>
string(3) "DNC"
}
Here's how I went about it for anyone else wondering
$SurveyOptions = preg_match_all('/(\d+)-([^|]+)/',
$res['survey_response_digit_map'], $matches);
$finalArray = array_combine($matches[1], $matches[2]);
Pretty straight forward.
Assuming the delimters: - and | do not exist in the keys or values, here is another non-regex way to tackle the string:
Code: (Demo)
$string = '1-Test Response|9-DNC|';
$string = str_replace(['-', '|'], ['=', '&'], $string); // generates: 1=Test Response&9=DNC&
parse_str($string, $result);
var_export($result);
Output:
array (
1 => 'Test Response',
9 => 'DNC',
)
If I have a string "123x456x78", how could I explode it to return an array containing "123" as the first element and "456" as the second element? Basically, I want to take strings that are followed by "x" (which is why "78" should be thrown out). I've been messing around with regular expressions, but am having trouble.
Thanks!
EDIT: if the string were "123x456x78x" I would need three elements: "123", "456", "78". Basically, for each region following an "x", I need to record the string up until the next "x".
Loads of different ways, but here's a RegEx as you were trying that:
$str = "123x456x78";
preg_match_all("/(\d+)x/", $str, $matches);
var_dump($matches[1]);
Output:
array(2) { [0]=> string(3) "123" [1]=> string(3) "456" }
$arr = explode("x", "123x456x78");
and then
unset($arr[2]);
if you really can't stand that poor 78.
use explode
$string='123x456x78';
$res = explode('x', $string);
if(count($res) > 0) {
echo $res[0];
if(count($res) > 1) {
echo $res[1];
}
}
$var = "123x456x78";
$array = explode("x", $var);
array_pop($array);
To explode AND remove the last result:
$string='123x456x78'; // original string
$res = explode('x', $string); // resulting array, exploded by 'x'
$c = count($res) - 1; // last key #, since array starts at 0 subtract 1
unset($res[$c]); // unset that last value, leaving you with everything else but that.
While I'm all for regular expressions, in this case it might be easier to just use PHP's array functions...
$result=array_slice(explode('x',$yourstring),0,-1);
This should work because only the last element returned by explode won't be followed by an 'x'. Not sure if explode will add an empty string as the last element if it ends on 'x' though, you might have to test that...
Use this below code to explode. It works well!
<?php
$str='123x456x78';
$res=explode('x',$str);
unset($res[count($res)-1]); // remove last array element
print_r($res);
?>
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I need to take only full words from a string i mean full words = words with more then 4 chars.
Example of a string:
"hey hello man are you going to write some code"
I need to return to:
"hello going write some code"
Also i need to trim all of these words and put them into a simple array.
Is it possible?
You could use a regular expression to do it.
preg_replace("/\b\S{1,3}\b/", "", $str);
You could then put them into an array with preg_split().
preg_split("/\s+/", $str);
Use str_word_count() http://php.net/manual/fr/function.str-word-count.php
str_word_count($str, 1)
Will return you a list of words, then count the ones with more than n letters using strlen()
The big advantage of using str_word_count() over other solutions such as preg_match or explode is that it will account for the punctuation and discard it from the final list of words.
Depending on your full requirements and if you need the string array unmodified too, you could use explode for this, something like this would get your words into an array:
$str = "hey hello man are you going to write some code";
$str_arr = explode(' ', $str);
Then you can use array_filter to remove the words you don't want, like so:
function min4char($word) {
return strlen($word) >= 4;
}
$final_str_array = array_filter($str_arr, 'min4char');
Otherwise if you don't need the unmodified array, you can use a regular expression to get all matches that are above a certain length using preg_match_all, or replace out the ones that are using preg_replace.
One final option would be to do it the basic way, use explode to get your array as per the first code example, and then loop over everything using unset to remove the entry from the array. But then, you'd also need to reindex (depending on your subsequent usage of the 'fixed' array), which could be inefficient depending on how large your array is.
EDIT: Not sure why there are claims that it does not work, see below for output of var_dump($final_str_array):
array(5) { [1]=> string(5) "hello" [5]=> string(5) "going" [7]=> string(5) "write" [8]=> string(4) "some" [9]=> string(4) "code" }
#OP, to convert this back to your string, you can simply call implode(' ', $final_str_array) to get this output:
hello going write some code
First, put them into an an array:
$myArr = explode(' ', $myString);
Then, loop through and assign only those with a length of 4 or greater to a new array:
$finalArr = array();
foreach ($myArr as $val) {
if (strlen($val) > 3) {
$finalArr[] = $val;
}
}
Obviously, if you have commas and other special characters in your string, it gets trickier, but for a basic design, I think this gets you moving in the right direction.
$strarray = explode(' ', $str);
$new_str = '';
foreach($strarray as $word){
if(strlen($word) >= 4)
$new_str .= ' '.$word;
}
echo $new_str;
Code Output
No loops required, no nested function calls, no temporary arrays. Just 1 function call and a very simple regex.
$string = "hey hello man are you going to write some code";
preg_match_all('/\S{4,}/', $string, $matches);
//Printing Values
print_r($matches[0]);
See it working
<?php
$word = "hey hello man are you going to write some code";
$words = explode(' ', $word);
$new_word;
foreach($words as $ws)
{
if(strlen($ws) > 4)
{
$new_word[] = $ws;
}
}
echo "<pre>"; print_r($new_word);
?>
You can use explode() and array_filter() with trim() + strlen() to achieve this. Try it and post your code if you're stuck.
I've got a string which consists of few sentences which are in curly brackets that I want to remove. That would be not that hard to do (as I know now.), but the real trouble is it's multilevel and all I want to strip is the top level brackets and leave everything inside intact. It looks something like this:
{Super duper {extra} text.} {Which I'm really {starting to} hate!} {But I {won't give up} so {easy}!} {Especially when someone is {gonna help me}.}
I want to create an array that would consist of those four entries:
Super duper {extra} text.
Which I'm really {starting to} hate!
But I {won't give up} so {easy}!
Especially when someone is {gonna help me}.
I have tried two ways, one was preg_split which didn't do much good:
$key = preg_split('/([!?.]{1,3}\} \{)/',$key, -1, PREG_SPLIT_DELIM_CAPTURE);
$sentences = array();
for ($i=0, $n=count($key)-1; $i<$n; $i+=2) {
$sentences[] = $key[$i].$key[$i+1]."<br><br>";
}
Another one was using preg_match_all which was quite good until I realized I had those brackets multilevel:
$matches = array();
$key = preg_match_all('/\{[^}]+\}/', $key, $matches);
$key = $matches[0];
Thanks in advance! :)
You can use a recursive expression like this:
/{((?:[^{}]++|(?R))*+)}/
The desired results will be in the first capturing group.
Usage, something like:
preg_match_all('/{((?:[^{}]++|(?R))*+)}/', $str, $matches);
$result = $matches[1];
$x="foo {bar {baz}} whee";
$re="/(^[^{]*){(.*)}([^}]*)$/";
print preg_replace($re, "\\1\\2\\3", $x) . "\n";'
returns:
foo bar {baz} whee