I have a single textarea input in my html form.
Users will write in that textarea like this:
5x Blue Flower
2 Red Flower
3* Yellow Flower
Purple Flower
So i need to get two arrays from this. One is a number and the other is the flower.
For now i got the numbers in array but i am struggling with getting only flowers in the second array.
Also, where they don't put a number, there should be a default number 1.
$text_data = $_POST['tekst'];
$input = explode("\n", $text_data);
foreach($input as $line)
{
$number = preg_replace("/[^0-9]/", '', $line);
echo $number . '<br>';
echo $line;
}
Any help would be much appreciated.
Try
foreach($input as $line){
preg_match("/\d+/", $line, $matches);
$line = preg_replace("/\d+/",'' ,$line);
$number = (isset($matches[0]))?$matches[0]:1;
if(strlen($line)>0){
echo $number."-->".$line."\n";
}
}
See demo here
Related
I want to search for two or more words, but not able to match the exact word.
If I use some other function like stripos() I don't get the required output.
$string = "abc india ltd";
$Arr = array('xyz ab','abc india', 'pqr', 'yz lmn');
$Arr = implode('',$Arr);
if (preg_match_all("/$string/", $Arr)) {
echo '<b>'.'found'.'<font color="green">'.$string.'</font>'.'</b>';
}
or (Both Same, But want to avoid using inside a loop)
$string = "abc india ltd";
$Arr = array('xyz ab','abc india', 'pqr', 'yz lmn');
foreach ($Arr as $value) {
if (preg_match_all("/$string/", $value)) {
echo '<b>'.'found '.'<font color="green">'.$string.'</font>'.'</b>';
}
}
I think you want like this:-
<?php
$string = "abc india";
$Arr = array('xyz india','abc india', 'pqr', 'yz lmn',"xyz abc india");
foreach($Arr as $val){
$explode_string = explode(" ",$string);
$counter =0;
foreach($explode_string as $explode_str){
if(strpos($val,$explode_str) !== FALSE){
$counter +=1;
}
}
if($counter>=2){
echo $val. " have exact ".$counter. " word matches";
echo PHP_EOL;
}
}
Output:-https://eval.in/831808
Note:- check it with all possible test-cases and let us know, worked or not?
This leverages some smart array functions to keep the code block concise and avoid manually incrementing a counter:
Code: (Demo)
$input_string="abc india ltd";
$input_array=explode(' ',$input_string);
$search_array=array('xyz ab','abc india','ltd abc','yz lmn');
foreach($search_array as $search_string){
if(sizeof(array_intersect($input_array,explode(' ',$search_string)))>1){
echo "More than one word in $search_string was found in $input_string\n";
}
}
Output:
More than one word in abc india was found in abc india ltd
More than one word in ltd abc was found in abc india ltd
*note, array_intersect() generates a new array that only contains elements that exist in both provided arrays. sizeof() is an alias of count().
ive been trying this by splitting the lines with substring and than using array unique on it but I cant get it to work properly. the idea is... if the same line is in the file with a lower number... keep the line with the higher number.
textfile:
wood tiger 22324 Squirrel
john apple 24574 Squirrel
peter snuggle 21234 Squirrel
james coolest 20108 Squirrel
james coolest 20134 Squirrel
output needed:
wood tiger 22324 Squirrel
john apple 24574 Squirrel
peter snuggle 21234 Squirrel
james coolest 20134 Squirrel
so it basically has to keep the highest numbered item if its the same line (the higher the number the newer the line is).
What I've tried so far:
$file_handle = fopen("file.txt", "rb" , FILE_SKIP_EMPTY_LINES);
while (!feof($file_handle) ) {
$line_of_text = fgets($file_handle);
if ($line_of_text[0] === ' ') continue;
if ($line_of_text[0] === ' ') continue;
$part1 = substr("$line_of_text", ..., ...);
$part2 = substr("$line_of_text", ..., ...);
$part3 = substr("$line_of_text", ..., ...);
$part1 = explode(' ', $part1);
$part1 = array_unique($part1);
$part1 = implode(' ', $part1);
var_dump ($part1);
}
file_put_contents('outputfile.txt', implode(PHP_EOL, $lines));
?>
Keep track of your "final" values in an associative array as you loop through the file. Compare each row to the array before adding it to avoid duplicates.
<?php
$file_handle = fopen("test.csv", "rb" , FILE_SKIP_EMPTY_LINES);
$finalArray = array();
$numberPartCol = 1;
while (($line_of_text = fgets($file_handle))) {
if ($line_of_text[0] === ' ') continue;
// why check the same thing twice?
// going to assume you have this part working as you didn't ask about it
$uniqueKeyPart = substr("$line_of_text", ..., ...);
// remove all the spaces so we can compare the numbers
$numberPart = str_replace(" ", "", substr("$line_of_text", ..., ...));
$squirrelPart = substr("$line_of_text", ..., ...);
if(!array_key_exists($uniqueKeyPart, $finalArray)) {
$finalArray[$uniqueKeyPart] = array(
// use preg_replace to get rid of all the extra whitespace
// if you don't want the spaces at all, just use str_replace as above
preg_replace("/ +/", " ", $uniqueKeyPart),
$numberPart,
preg_replace("/ +/", " ", $squirrelPart)
);
}
else {
if($finalArray[$uniqueKeyPart][$numberPartCol] < $numberPart) {
$finalArray[$uniqueKeyPart][$numberPartCol] = $numberPart;
}
}
}
// loop through $finalArray to put the data in the format you want for the outputfile.txt
$lines = array();
foreach($finalArray as $row) {
$lines = implode(",", $row) . PHP_EOL;
}
file_put_contents('outputfile.txt', $lines);
?>
fgetcsv()
Please do consider changing how the data is stored in the first place. My sympathies if you have no control over that :(
I have some data in the following format.
Orange - $3.00
Banana - $1.25
I would like to print this as only as follows:
Orange
Banana
I tried using following code in a loop but the data may have 0 in other places as well. So if I can find 0 only at the end for a specific line.
$pos=strpos($options, "0");
$options = substr($options, 0, $pos)."\n";
Any ideas?
Is this what you're looking for?
<?php
$input = 'Orange - $3.00';
list($fruit, $price) = explode('-', $input);
?>
Or if you want to proces all the input:
<?php
$input = 'Orange - $3.00
Banana - $1.25';
$fruitlist = array();
$sepLines = explode("\n", $input);
foreach($seplines as $line)
{
list($fruit, $price) = explode(' - ', $line);
$fruitlist[] = $fruit;
}
?>
Are you trying to print only the name of the item and not the price?
$n=explode(" - ", "Banana - $1.25");
print $n[0];
$string = explode("-", $originalText);
$word = $string[0];
and thats it :)
Assume I have the following string:
I have | been very busy lately and need to go | to bed early
By splitting on "|", you get:
$arr = array(
[0] => I have
[1] => been very busy lately and need to go
[2] => to bed early
)
The first split is after 2 words, and the second split 8 words after that. The positions after how many words to split will be stored: array(2, 8, 3). Then, the string is imploded to be passed on to a custom string tagger:
tag_string('I have been very busy lately and need to go to bed early');
I don't know what the output of tag_string will be exactly, except that the total words will remain the same. Examples of output would be:
I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p
I-ee have been-vb very busy-df lately-nn and need-f to go to bed-uu early-yy
This will lengthen the string by an unknown number of characters. I have no control over tag_string. What I know is (1) the number of words will be the same as before and (2) the array was split after 2, and thereafter after 8 words, respectively. I now need a solution explode the tagged string into the same array as before:
$string = "I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p"
function split_string_again() {
// split after 2nd, and thereafter after 8th word
}
With output:
$arr = array(
[0] => I have-nn
[1] => been-vb very-vb busy lately and-rr need to-r go
[2] => to bed early-p
)
So to be clear (I wasn't before): I cannot split by remembering the strpos, because strpos before and after the string went through the tagger, aren't the same. I need to count the number of words. I hope I have made myself more clear :)
You wouldn't want to count the number of words, you would want to count the string length (strlen). If it is the same string without the pipes, then you want to split it with substr after a certain amount.
$strCounts = array();
foreach ($arr as $item) {
$strCounts[] = strlen($item);
}
// Later on.
$arr = array();
$i = 0;
foreach ($strCounts as $count) {
$arr[] = substr($string, $i, $count);
$i += $count; // increment the start position by the length
}
I have not tested this, simply a "theory" and probably has some kinks to work out. There may be a better way to go about it, I just don't know it.
Interesting question, although I think the rope data structure still applies it might be a little overkill since word placement won't change. Here is my solution:
$str = "I have | been very busy lately and need to go | to bed early";
function get_breaks($str)
{
$breaks = array();
$arr = explode("|", $str);
foreach($arr as $val)
{
$breaks[] = str_word_count($val);
}
return $breaks;
}
$breaks = get_breaks($str);
echo "<pre>" . print_r($breaks, 1) . "</pre>";
$str = str_replace("|", "", $str);
function rebreak($str, $breaks)
{
$return = array();
$old_break = 0;
$arr = str_word_count($str, 1);
foreach($breaks as $break)
{
$return[] = implode(" ", array_slice($arr, $old_break, $break));
$old_break += $break;
}
return $return;
}
echo "<pre>" . print_r(rebreak($str, $breaks), 1) . "</pre>";
echo "<pre>" . print_r(rebreak("I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p", $breaks), 1) . "</pre>";
Let me know if you have any questions, but it is pretty self explanatory. There are definitely ways to improve this as well.
I'm not quite sure I understood what you actually wanted to achieve. But here are a couple of things that might help you:
str_word_count() counts the number of words in a string. preg_match_all('/\p{L}[\p{L}\p{Mn}\p{Pd}\x{2019}]*/u', $string, $foo); does pretty much the same, but on UTF-8 strings.
strpos() finds the first occurrence of a string within another. You could easily find the positions of all | with this:
$pos = -1;
$positions = array();
while (($pos = strpos($string, '|', $pos + 1)) !== false) {
$positions[] = $pos;
}
I'm still not sure I understood why you can't just use explode() for this, though.
<?php
$string = 'I have | been very busy lately and need to go | to bed early';
$parts = explode('|', $string);
$words = array();
foreach ($parts as $s) {
$words[] = str_word_count($s);
}
I have some data in a string in the format key: value key: value key: value etc...
I'm trying to turn it into an array using a regex match. The keys are all uppercase letters directly followed by a colon. Then there is a space and the value starts. This is then followed by a space and then the next key. The value can contain upper/lowercase letters, numbers, space, comma or equals sign.
For example, I'd like this input string:
NAME: Name of Item COLOR: green SIZE: 40
Turned into this array:
newArray[NAME] = Name of Item
newArray[COLOR] = green
newArray[SIZE] = 40
Any help is much appreciated. Also I don't have access to the formatting of the input, or I'd make this a lot easier on myself.
A generic solution:
$str = 'NAME: Name of Item COLOR: green SIZE: 40';
$split = preg_split('/([A-Z]+):/', $str, -1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
echo 'Split Array is: ' . var_export($split, true);
$newArray = array();
// Stick the key and value together (processing two entries at a time.
for ($i = 0; $i < count($split) - 1; $i = $i + 2)
{
$newArray[$split[$i]] = trim($split[$i + 1]); // Probably trim them.
}
echo 'New Array is: ' . var_export($newArray, true);
I'd suggest
$str = "NAME: Name of Item COLOR: green SIZE: 40";
preg_match_all('~([A-Z]+):(.+?)(?=[A-Z]+:|$)~', $str, $m, PREG_SET_ORDER);
foreach($m as $e)
$result[$e[1]] = trim($e[2]);
print_r($result);