This question already has answers here:
Converting a number with comma as decimal point to float
(9 answers)
str_pad with a float in php?
(2 answers)
Remove non-numeric characters (excluding periods and commas) from a string (i.e. remove all characters except numbers, commas, and periods)
(5 answers)
Closed 3 years ago.
This is my code where I read csv file (which I get from the bank), parsing it into array & insert it into database:
$csvFile = file('tecajnica.csv');
$keys = str_getcsv(array_shift($csvFile), ';');
foreach ($csvFile as $csvRecord) {
// combine our $csvRecord with $keys array
$csv[] = array_combine($keys, str_getcsv($csvRecord, ';'));
}
foreach( $csv as $row) {
$db2 = new PDO ("odbc:as400");
$sqlf93p = $db2->prepare("INSERT INTO..... VALUES (".$row['sifra'].",".$row['Kupovni2']." ......)
$sqlf93p->execute();
This is how my array looks like:
[0]=>
array(10) {
["id"]=>
string(2) "67"
["drzava"]=>
string(10) "Australija"
["sifra"]=>
string(7) "036 AUD"
["VrijediZa"]=>
string(1) "1"
["Kupovni1"]=>
string(8) "4,5207"
["Kupovni2"]=>
string(8) "4,589597"
}
[1]=>
array(10) {
["id"]=>
string(0) ""
["drzava"]=>
string(5) "Ceska"
["sifra"]=>
string(7) "203 CZK"
["VrijediZa"]=>
string(1) "1"
["Kupovni1"]=>
string(8) "0,277098"
["Kupovni2"]=>
string(8) "0,2821"
}
* * * * * * * etc * * * * * *
So my questions are:
1) Howto convert ["sifra"]=> "203 CZK" to ["sifra"]=> "203" (I want only numeric value to appear before insert)?
2) Howto convert ["Kupovni2"]=> "0,2821" to ["Kupovni2"]=> "0,282100" (I want 6 decimal places before insert)?
Thanks.
Another option could be to replace all non digits using \D+ with an empty string.
$digitsOnly = preg_replace('/\D+/', '', "203 CZK");
echo $digitsOnly; // 203
For appending the zeroes, you might use str_pad:
$parts = explode(',', '0,2821');
$str = implode(',', [$parts[0], str_pad($parts[1], 6, '0', STR_PAD_RIGHT)]);
echo $str; // 0,282100
Php demo
Your code might look like:
foreach( $csv as $row) {
$db2 = new PDO ("odbc:as400");
$sifra = preg_replace('/\D+/', '', $row['sifra']);
$parts = explode(',', $row['Kupovni2']);
$kupovni2 = implode(',', [$parts[0], str_pad($parts[1], 6, '0', STR_PAD_RIGHT)]);
$sqlf93p = $db2->prepare("INSERT INTO..... VALUES (". $sifra . "," . $kupovni2 ." ......);
$sqlf93p->execute();
To get number from a string you can do it this way
$string = '203 CZK';
echo (int) $string;
OR
$string = '203 CZK';
echo filter_var($string, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
To make string to length 8 you can use str_pad
$string = '0,2821';
echo str_pad($string, 8, "0", STR_PAD_RIGHT);
Result :-
0,282100
Related
This question already has answers here:
Extract a substring between two characters in a string PHP
(11 answers)
Closed 10 months ago.
I was wondering... I have two strings :
"CN=CMPPDepartemental_Direction,OU=1 - Groupes de sécurité,OU=CMPP_Departementale,OU=Pole_Ambulatoire,OU=Utilisateurs_ADEI,DC=doadei,DC=wan",
"CN=CMPPDepartemental_Secretariat,OU=1 - Groupes de sécurité,OU=CMPP_Departementale,OU=Pole_Ambulatoire,OU=Utilisateurs_ADEI,DC=doadei,DC=wan"
Is there a way in php to select only the first part of these strings ? I would like to just select CMPPDepartemental_Direction and CMPPDepartemental_Secretariat.
I had thought of trying with substr() or trim() but without success.
You should use preg_match with regex CN=(\w+_\w+) to extract needed parts:
$strs = [
"CN=CMPPDepartemental_Direction,OU=1 - Groupes de sécurité,OU=CMPP_Departementale,OU=Pole_Ambulatoire,OU=Utilisateurs_ADEI,DC=doadei,DC=wan",
"CN=CMPPDepartemental_Secretariat,OU=1 - Groupes de sécurité,OU=CMPP_Departementale,OU=Pole_Ambulatoire,OU=Utilisateurs_ADEI,DC=doadei,DC=wan"
];
foreach ($strs as $str) {
$matches = null;
preg_match('/CN=(\w+_\w+)/', $str, $matches);
echo $matches[1];
}
If the strings always have the same structure, I recommend using a custom function find_by_keyword - so you can search for other keywords too.
function find_by_keyword( $string, $keyword ) {
$array = explode(",",$string);
$found = [];
// Loop through each item and check for a match.
foreach ( $array as $string ) {
// If found somewhere inside the string, add.
if ( strpos( $string, $keyword ) !== false ) {
$found[] = substr($string, strlen($keyword));
}
}
return $found;
}
var_dump(find_by_keyword($str2, "CN="));
// array(1) {
[0]=>
string(27) "CMPPDepartemental_Direction"
}
var_dump(find_by_keyword($str2, "OU="));
//array(4) {
[0]=>
string(25) "1 - Groupes de sécurité"
[1]=>
string(4) "CMPP"
[2]=>
string(4) "Pole"
[3]=>
string(12) "Utilisateurs"
}
Examle here.
Note: I can't use break or next line functions as i am using FPDF
I am having a problem with php strings. I am having a string where i want to show atmost 12 characters in first row and remaining in second row. So basically i want to break string into two parts and assign to two variables so that i can print those two variables. I have tried following code :-
if($length > 12)
{
$first400 = substr($info['business_name'], 0, 12);
$theRest = substr($info['business_name'], 11);
$this->Cell(140,22,strtoupper($first400));
$this->Ln();
$this->Cell(140,22,strtoupper($theRest));
$this->Ln();
}
But using this I am getting as shown below :
Original String : The Best Hotel Ever
Output :
The Best Hot
Tel Ever
It is breaking a word, i don't want to break the word, just check the length and if within 12 characters all the words are complete then print next word in next line. Like this :
Desired OutPut:
The Best
Hotel Ever
Any suggestions ?
I see no built-in function to do it, however you could explode on spaces, and re-build your string until the length with the next words get over 12, everything else going to the second part :
$string = 'The Best Hotel Ever';
$exp = explode(' ', $string);
if (strlen($exp[0]) < 12) {
$tmp = $exp[0];
$i = 1;
while (strlen($tmp . ' ' . $exp[$i]) < 12) {
$tmp .= " " . $exp[$i];
$i++;
}
$array[0] = $tmp;
while (isset($exp[$i])) {
$array[1] .= ' ' . $exp[$i];
$i++;
}
$array[1] = trim($array[1]);
} else {
$array[0] = '';
$array[1] = trim(implode (' ', $exp));
}
var_dump($array);
// Output : array(2) { [0]=> string(8) "The Best" [1]=> string(10) "Hotel Ever" }
// $string1 = 'The';
// array(2) { [0]=> string(3) "The" [1]=> string(0) "" }
// $string2 = 'Thebesthotelever';
// array(2) { [0]=> string(0) "" [1]=> string(16) "Thebesthotelever" }
Im not too crash hot on PHP but it seems to be a simple case of which element of the string you are accessing is futher across from where you want to be:
Try:
if($length > 12)
{
$first400 = substr($info['business_name'], 0, 8);
$theRest = substr($info['business_name'], 11);
$this->Cell(140,22,strtoupper($first400));
$this->Ln();
$this->Cell(140,22,strtoupper($theRest));
$this->Ln();
}
For further help check out because you need to remember to count from zero up:
http://php.net/manual/en/function.substr.php
I have created a Array and are not able to echo values from it. Below I have copy pasted source code results from my browser. As you can see "]=> starts on new line. How can I solve this
using this function:
function remap_alternating(array $values) {
$remapped = array();
for($i = 0; $i < count($values) - 1; $i += 2) {
$remapped[strip_tags(trim($values[$i], " "))] = strip_tags(trim($values[$i + 1], " "));
}
return $remapped;
}
$mapped = remap_alternating($matches[0]);
$keys = str_replace( ':', '', array_keys($mapped) );
$values = array_values($mapped);
$mapped = array_combine($keys, $values);
Result of var_dump($mapped); (Copy Paste from Browser Source Code)
array(32) {
["Age
"]=>
string(9) "21 Yrs.
"
["Ethnicity
"]=>
string(6) "Black
"
["Location
"]=>
string(36) "Dubai, Dubayy, United Arab Emirates
"
My question is how I can get echo $mapped[Age];to work?
Thank you
You can specify the characters to trim in the second argument of trim(): http://us2.php.net/trim
You look to be specifying only " ", in the trim() function you're using. Leave the second argument blank so it will trim the default characters which includes \n.
firstly, I very much apologize for my poorly written title of this question. So please someone with native English, change the title appropriately. My question is rather simple, it follows:
I am using integer to store multiple types of one item. For example:
TYPE A = 1
TYPE B = 2
TYPE C = 4
TYPE D = 8
TYPE E = 16
etc...
Now the item in DB has type value 14, that means that it has been assigned to TYPE B+C+D. If it would have type value for example 9, it would mean it has been assigned to TYPE A+D.
I need a function which I would supply with single type integer and this function would return array of integer types.
I could iterate through all the integers and compare them with the number, but that's what I am using now, but I am looking for some more effective way, if it exists ?
Thanks in advance for your help.
Here's a function without any loops (mostly done for the fun of it :) ):
function getTypes($int)
{
$types = array('Type A','Type B','Type C','Type D','Type E');//defining types
$t = array_reverse(str_split(decbin($int)));//converting $int to an array of bits
$types = array_slice($types,0,ceil(log($int,2)));//slicing the array to the same size as number of bits in the $int
$t = array_combine($types,$t);// Creating a new array where types are keys and bits are values
return array_keys($t,1);// returning an array of keys which have a value of 1
}
However it doesn't mean that it is efficient. If you use a bitmask you better of checking values using bitwise operators like bitwise and (&).
For example if you want to check if your integer contains Type D and Type E you should do
if ($integer & 8 & 16)
To check for each individual type I would us a loop with bitshift operator
function getTypes($int)
{
$result = array();
$types = array('Type A','Type B','Type C','Type D','Type E');
foreach($types as $type)
{
if ($int & 1)//checking if last bit is 1 (exactly the same as if($int%2) )
$result[]=$type;
$int>>=1;//shifting integer's bits to the right (exactly the same as $int = $int / 2)
}
return $result;
}
How's this? http://codepad.org/AzgdPsL1
To explain what's going on:
I create a $types array of all the valid types that exist between the range of 1 to $max_bit bits.
Looping while the number is greater than 0, it gets bitwise ANDed with 1. If it turns out that evaluates to true, this means that the LSB is set, so the type at the head of the $type array applies to this number. The current type is added to the return array.
The number is then shifted to the right by one bit.
<?php
function num2type( $num)
{
$max_bit = 5;
$types = array_combine( range( 1, $max_bit), range( ord( 'A'), ord( 'A') + $max_bit - 1));
$return = array();
while( $num > 0)
{
$current_type = array_shift( $types);
if( $num & 0x1)
{
$return[] = chr( $current_type);
}
$num = $num >> 1;
}
return $return;
}
var_dump( num2type( 8)); // array(1) { [0]=> string(1) "D" }
var_dump( num2type( 31));
var_dump( num2type( 14));
Output (for 31):
array(5) {
[0]=>
string(1) "A"
[1]=>
string(1) "B"
[2]=>
string(1) "C"
[3]=>
string(1) "D"
[4]=>
string(1) "E"
}
Output for 14:
array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "D"
}
function check_flag($field, $bit)
{
return (($field | $bit) === $field) ? TRUE : FALSE;
}
$types = array('A' => 1, 'B' => 2, 'C' => 4, 'D' => 8, 'E' => 16);
$db_value = 14;
var_dump(check_flag($db_value, $types['B']));
... just make sure that you cast the value fetched from the database to integer.
Edit: Now that I read you need all of the types that are set, here's some more logic:
$set = array();
foreach ($types as $key => $value)
if (check_flag($db_value, $value)) $set[] = $key;
$a = 10;
$scan = 1;
$result = array();
while ($a >= $scan){
if ($a & $scan)
$result[] = $scan;
$scan<<=1; //just a bit shift
}
var_dump($result);
This question already has answers here:
preg_match and UTF-8 in PHP
(8 answers)
Closed 12 months ago.
I have preg_match_all('/[aäeëioöuáéíóú]/u', $in, $out, PREG_OFFSET_CAPTURE);
If $in = 'hëllo' $out is:
array(1) {
[0]=>
array(2) {
[0]=>
array(2) {
[0]=>
string(2) "ë"
[1]=>
int(1)
}
[1]=>
array(2) {
[0]=>
string(1) "o"
[1]=>
int(5)
}
}
}
The position of o should be 4. I've read about this problem online (the ë gets counted as 2). Is there a solution for this? I've seen mb_substr and similar, but is there something like this for preg_match_all?
Kind of related: Is their an equivalent of preg_match_all in Python? (Returning an array of matches with their position in the string)
This is not a bug, PREG_OFFSET_CAPTURE refers to the byte offset of the character in the string.
mb_ereg_search_pos behaves the same way. One possibility is to change the encoding to UTF-32 before and then divide the position by 4 (because all unicode code units are represented as 4-byte sequences in UTF-32):
mb_regex_encoding("UTF-32");
$string = mb_convert_encoding('hëllo', "UTF-32", "UTF-8");
$regex = mb_convert_encoding('[aäeëioöuáéíóú]', "UTF-32", "UTF-8");
mb_ereg_search_init ($string, $regex);
$positions = array();
while ($r = mb_ereg_search_pos()) {
$positions[] = reset($r)/4;
}
print_r($positions);
gives:
Array
(
[0] => 1
[1] => 4
)
You could also convert the binary positions into code unit positions. For UTF-8, a suboptimal implementation is:
function utf8_byte_offset_to_unit($string, $boff) {
$result = 0;
for ($i = 0; $i < $boff; ) {
$result++;
$byte = $string[$i];
$base2 = str_pad(
base_convert((string) ord($byte), 10, 2), 8, "0", STR_PAD_LEFT);
$p = strpos($base2, "0");
if ($p == 0) { $i++; }
elseif ($p <= 4) { $i += $p; }
else { return FALSE; }
}
return $result;
}
There is simple workaround, to be used after preg_match() results matched. You need to iterate every match result and reassign position value with following:
$utfPosition = mb_strlen(substr($wholeSubjectString, 0, $capturedEntryPosition), 'utf-8');
Tested on php 5.4 under Windows, depends on Multibyte PHP extension only.
PHP doesn't support unicode very well, so a lot of string functions, including preg_*, still count bytes instead of characters.
I tried finding a solution by encoding and decoding strings, but ultimately it all came down to the preg_match_all function.
About the python thing: a python regex matchobject contains the match position by default mo.start() and mo.end(). See: http://docs.python.org/library/re.html#finding-all-adverbs-and-their-positions
Another way how to split UTF-8 $string by a regular expression is to use function preg_split(). Here is my working solution:
$result = preg_split('~\[img/\d{1,}/img\]\s?~', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
PHP 5.3.17