How to loop over a string's characterss? - php

Basically, I have an array of strings, and I want to check if each character in each string is in a predefined $source string. Here is how I think it should be done:
$source = "abcdef";
foreach($array as $key => $value) {
foreach(char in $value) {
if(char is not in source)
unset($array[$key]); //remove the value from array
}
}
If this is a correct logic, how to implement the foreach and the if parts?

You could try this:
$array = array('1' => 'cab', '2' => 'bad', '3' => 'zoo');
$source = "abcdef";
foreach($array as $key => $value) {
$split = str_split($value);
foreach($split as $char){
$pos = strrpos($source, $char);
if ($pos === false) {
unset($array[$key]);
break;
}
}
}
Result:
array(2) {
[1]=>
string(3) "cab"
[2]=>
string(3) "bad"
}
DEMO: http://codepad.org/fU99Gdtd

Try this code:
$source = "abcdef";
foreach($array as $key => $value) {
$ichr = strlen($value) - 1;
// traverses each character in string
for($i=0; $i<$ichr; $i++) {
if(stristr($value{$i}) === false) {
unset($array[$key]);
break;
}
}
}

$array = array("abc","defg","asd","ade","de","fe");
$source = "abcde";
foreach ($array as $key => $string){
for($i=0;$i<strlen($string);$i++){
if(strpos($source, $string[$i])===false){
unset($array[$key]);
}
}
}
Now the array looks like
array(3) {
[0]=>
string(3) "abc"
[3]=>
string(3) "ade"
[4]=>
string(2) "de"
}

As I understand you want to filter ( remove ) the characters, that are not defined in the $source variable. By Mark Baker comments, this is what you need:
$source = str_split ( "abdef" ); //defined characters
$target = str_split ( "atyutyu" ); //string to be filtered
$result = array_intersect ( $target, $source );
echo implode( $result ); // output will be only "a"
And full example:
$source = str_split ( "abdef" );
$txts = array ( "alfa", "bravo", "charlie", "delta" );
function filter ( $toBeChecked, $against )
{
$target = str_split ( $toBeChecked );
return implode ( array_intersect ( $target, $against ) );
}
foreach ( $txts as &$value )
{
$value = filter ( $value, $source );
}
foreach ( $txts as $value )
{
echo $value . ", ";
}
//output afa, ba, ae, ae

$array = array(
'abacab',
'baccarat',
'bejazzle',
'barcode',
'zyx',
);
$source = "abcde";
$sourceArray = str_split($source);
foreach($array as $value) {
$matches = array_intersect($sourceArray, str_split($value));
echo $value;
if (count($matches) == 0) {
echo ' contains none of the characters ', $source, PHP_EOL;
} elseif (count($matches) == count($sourceArray)) {
echo ' contains all of the characters ', $source, PHP_EOL;
} else {
echo ' contains ', count($matches), ' of the characters ', $source, ' (', implode($matches), ')', PHP_EOL;
}
}
gives
abacab contains 3 of the characters abcde (abc)
baccarat contains 3 of the characters abcde (abc)
bejazzle contains 3 of the characters abcde (abe)
barcode contains all of the characters abcde
zyx contains none of the characters abcde

Related

The string is converted to an array several times

I want to convert the string to an array.The following example.
1.Capitalize the first letter
2.The letter after ',' or '_' becomes capital
3.Strings are separated by ','
4.swap underline to ' '
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
//convert to
$arr_1 = ('Ab','Cb Ef','Kk','Uu');
$arr_2 = ('Cb Ef','Kk','Uu');
$arr_3 = ('Cb Ef','Kk','Uu');
//There are my code and result .
$func = function( $str ){
$str_len = strlen( $str );
for ( $i = 0 ; $i < $str_len ; $i++ )
{
if ( $str[ $i ] == ',' && $str[ $i ] == '_' )
{
$str[ $i ] = $str[ $i ] == '_' ? ' ' : $str[ $i ] ;
if ( ord( $str[ $i +1 ] ) <= 122 && ord( $str[ $i +1 ] ) >= 97 )
{
$str[ $i ] = chr( ord( $str[ ++$i ] ) - 32 );
}
}
}
return $str;
};
var_dump(explode( ',' , $func( 'ss,adsa_sdfs' )));
//result is this
array(2) { [0]=> string(2) "ss" [1]=> string(9) "adsa_sdfs" }
Try this
function conv( $str ) {
$res = [];
$arr = explode( ',' , $str );
foreach ( $arr as $key => $value ) {
$res[] = ucwords( str_replace( '_' , ' ' , $value ) );
}
return $res;
}
var_dump( conv( 'ss,adsa_sdfs' ) );
Response:
array(2) { [0]=> string(2) "Ss" [1]=> string(9) "Adsa Sdfs" }
The demo code with your test cases:
<?php
function upper($s, $sep)
{
// upper the char separated by $sep
$a = explode($sep, $s);
$a = array_map('ucfirst', $a);
return join($sep, $a);
}
function test($s)
{
// upper the chars separated by '_'
$s = upper($s, '_');
// upper the chars separated by ','
$s = upper($s, ',');
// change all '_' to ' ' and upper the chars
$s = str_replace('_', ' ', $s);
$s = upper($s, ' ');
// trim unused chars
$s = trim($s, ' ,');
return explode( ',', $s);
}
$tests = [
"_ab,cb_ef,kk,uu" => ['Ab','Cb Ef','Kk','Uu'],
",cb_ef,kk,uu" => ['Cb Ef','Kk','Uu'],
"cb_ef,kk,uu" => ['Cb Ef','Kk','Uu'],
"ss,adsa_sdfs" => ['Ss', 'Adsa Sdfs'],
];
foreach ($tests as $s=>$a) {
$out = test($s);
if ($out === $a) {
echo "OK! $s = " . json_encode($a) . PHP_EOL;
} else {
echo "WRONG! $s is " . json_encode($out) . PHP_EOL;
}
}
Output:
OK! _ab,cb_ef,kk,uu = ["Ab","Cb Ef","Kk","Uu"]
OK! ,cb_ef,kk,uu = ["Cb Ef","Kk","Uu"]
OK! cb_ef,kk,uu = ["Cb Ef","Kk","Uu"]
OK! ss,adsa_sdfs = ["Ss","Adsa Sdfs"]
Write this
<?php
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
function convert_to($arr){
$arr = str_replace('_', ' ', $arr);
$arr_1 = explode(",",$arr);
$new_array = array_map('trim', $arr_1);
$new_array = array_map('ucwords', $arr_1); // first letter after word capitalize
$new_array = array_filter($new_array, 'strlen'); // remove empty item
$new_array = array_values($new_array); // arrange and shift after removing empty item
return $new_array;
}
$arr_1 = convert_to($str_1);
$arr_2 = convert_to($str_2);
$arr_3 = convert_to($str_3);
var_dump($arr_1);
var_dump($arr_2);
var_dump($arr_3);
Output :
array(4) {
[0]=>
string(3) " Ab"
[1]=>
string(5) "Cb Ef"
[2]=>
string(2) "Kk"
[3]=>
string(2) "Uu"
}
array(3) {
[0]=>
string(5) "Cb Ef"
[1]=>
string(2) "Kk"
[2]=>
string(2) "Uu"
}
array(3) {
[0]=>
string(5) "Cb Ef"
[1]=>
string(2) "Kk"
[2]=>
string(2) "Uu"
}
You could use PHP's built-in functions for this kind of situation:
function processString($param){
$explode = explode(',', $param);
$replace = str_replace('_', ' ', $explode);
$replace = array_map('trim', $replace);
$ucfirst = array_map('ucwords', $replace);
return $ucfirst;
}
The explanation is:
First we convert the string to array based on comma separation using explode() method.
Next, we need to convert underscore into space using str_replace() method.
I noticed in your example that string with space (previously underscore) in it is stripped. This need to be implemented using trim(). Since the string already converted into array, we use array_map() method to process trim for all array values.
Finally, convert every word to uppercase. Fortunately, PHP already have the method: ucwords(). Just need to array_map() it.
This is how you test the code:
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
print_r(processString($str_1));
print_r(processString($str_2));
print_r(processString($str_3));
Try the following code:
<?php
function ConvertToArr($str)
{
$result = array();
$temp_arr1 = explode(",", $str);
for ($count1 = 0; $count1 < count($temp_arr1); $count1++) {
$temp_results = array();
$temp_arr2 = explode("_", $temp_arr1[$count1]);
for ($count2 = 0; $count2 < count($temp_arr2); $count2++) {
$temp_str = ucfirst($temp_arr2[$count2]);
if ($temp_str != "")
$temp_results []= $temp_str;
}
$temp_results = implode(" ", $temp_results);
if (trim($temp_results) != "")
$result []= $temp_results;
}
return $result;
}
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
print_r(ConvertToArr($str_1));
print_r(ConvertToArr($str_2));
print_r(ConvertToArr($str_3));
?>
It produces the following output:
Array
(
[0] => Ab
[1] => Cb Ef
[2] => Kk
[3] => Uu
)
Array
(
[0] => Cb Ef
[1] => Kk
[2] => Uu
)
Array
(
[0] => Cb Ef
[1] => Kk
[2] => Uu
)

how to convert string to array character

The first line of code is converted to the second code. I can use the padding methods, but I want to get the solution from the shortest path and convert it quickly. I will use the code field in the sql select section
$it = "(a(am,bam),b(dam,cam))";
$to = "a.am, a.bam, b.dam, b.cam";
Try following code:
$it = "(a(am,bam),b(dam,cam))";
function iDelimiter( $str ) {
$count = 0;
$str = str_split( $str );
foreach( $str as &$value ) {
if( $value == "(" ) {
$count++;
} elseif( $value == ")" ) {
$count--;
}
if( $value == "," && ! $count ) {
$value = "|";
}
}
return explode( "|", implode( $str ) );
}
function iParser( $str, $_prefix = "" ) {
preg_match( "/^((?!(\(|\))).)*\((.*)\)$/", $str, $m );
if( count( $m ) < 4 ) {
return ( strlen( $_prefix ) ? $_prefix . "." : '' ) . $str;
}
$prefix = ( strlen( $_prefix ) ? $_prefix . "." : '' ) . $m[1];
$str = $m[3];
if( strpos( $str, "(" ) === false ) {
$return = explode( ",", $str );
$pad = preg_filter( '/^/', strlen( $prefix ) ? $prefix . '.' : '', $return );
return implode( $pad, "," );
} else {
$str = iDelimiter( $str );
$return = array_map( 'iParser', $str, array_pad( array(), count( $str ), $prefix ) );
return implode( $return, ", " );
}
}
print_r( iParser( $it ) );
It parse every depth of parentheses. Just pass your string to iParser function.
Try this:
<?php
function str2Arr( $s, $r, $str) {
$str = trim( str_replace( $s, $r, $str ));
return explode(" ", $str);
}
$it = "(a(am,bam),b(dam,cam))";
//$to = "a.am, a.bam, b.dam, b.cam";
$search = ['),', '(', ')', ',', 'a a', 'b d', 'ba', 'c'];
$replace =[' ', ' ', ' ', ' ', 'a.a','b.d', 'a.ba', 'b.c'];
var_dump( implode(", ",( str2Arr( $search, $replace, $it) ) ) );
See demo
Without using a regex one may achieve the specified conversion by using str_replace() which uses an array of characters to be replaced by another array of characters when found in the subject string. The non-alphabetical characters are each replaced with blank space and the substrings are replaced so that each starts with an "a" or "b" as appropriate followed by a period and the rest of the substring.
Kill me now. There's got to be a better way, but my eyes are bleeding.
It probably would have worked much better had I started with a regex, but my regex skills are rusty.
I kept pounding your data with a hammer until the square peg went through the round hole.
<?php
$it = "(a(am,bam),b(dam,cam))";
$it = substr($it, 1, -1);
//$to = "a.am, a.bam, b.dam, b.cam";
$final = [];
$test = explode("),", $it);
foreach($test as $section) {
$letter = substr($section, 0, 1);
$remainder = substr($section, 2);
if(strpos($remainder, ")")) {
$remainder = substr($remainder, 0, strpos($remainder, ")"));
}
echo $letter . " ".$remainder."\n";
foreach(explode(",", $remainder) as $fragment) {
array_push($final, $letter.".".$fragment);
}
}
var_dump($final);
var_dump(implode($final, ", "));
Yields
a am,bam
b dam,cam
array(4) {
[0]=>
string(4) "a.am"
[1]=>
string(5) "a.bam"
[2]=>
string(5) "b.dam"
[3]=>
string(5) "b.cam"
}
string(22) "a.am, a.bam, b.dam, b.cam"

foreach concatenate each element to next one

I would like to concatenate each element of array to next one. I want the output array to be:
Array
(
[0] => test
[1] => test/test2
[2] => test/test2/test3
[3] => test/test2/test3/test4
)
I tried the following way which concatenates each string to itself:
$url = preg_split("/[\s\/]+/", "test/test2/test3/test4");
foreach ($url as $dir) {
$dir .= $dir;
}
Any help appreciated.
Maybe another way
<?php
$data = array( 'test', 'test2', 'test3', 'test4' );
for( $i = 0; $i < count( $data ); $i++ )
{
if( $i != 0 )
{
$new[ $i ] = $new[ $i - 1 ] .'/'. $data[ $i ];
}
else
{
$new[ $i ] = $data[ $i ];
}
}
var_dump( $new );
Output
array(4) {
[0]=>
string(4) "test"
[1]=>
string(10) "test/test2"
[2]=>
string(16) "test/test2/test3"
[3]=>
string(22) "test/test2/test3/test4"
}
You should obtain the result you need in $my_array
$url = explode("/", "test/test2/test3/test4");
$str ='';
foreach($url as $key => $value){
if ( $str == '') {
$str .= $str;
} else {
$str .= '/'.$str;
}
$my_array[$key] = $str ;
echo $str . '<br />';
}
var_dump($my_array);
$url = preg_split("/[\s\/]+/", "test/test2/test3/test4");
$arr = array();
$str = '';
foreach ($url as $key => $dir) {
if ($key !== 0) {
$str .= '/' . $dir;
} else {
$str .= $dir;
}
$arr[] = $str;
}
On each iteration concate a string with new value and add it as a separate value for your output array.
Here's a quick way. For simple splitting just use explode():
$url = explode("/", "test/test2/test3/test4");
foreach($url as $value) {
$temp[] = $value;
$result[] = implode("/", $temp);
}
Each time through the loop, add the current value to a temporary array and implode it into the next element of the result.

How to extract keywords from bengali text using PHP

I want to extract keywords automatically from Bengali text files using php.I have this code for reading a Bengali text file.
<?php
$target_path = $_FILES['uploadedfile']['name'];
header('Content-Type: text/plain;charset=utf-8');
$fp = fopen($target_path, 'r') or die("Can't open CEDICT.");
$i = 0;
while ($line = fgets($fp, 1024))
{
print $line;
$i++;
}
fclose($fp) or die("Can't close file.");
And I found following codes to extract most common 10 keywords but it's not working for Bengali texts. What changes should I make?
function extractCommonWords($string){
$stopWords = array('i','a','about','an','and','are','as','at','be','by','com','de','en','for','from','how','in','is','it','la','of','on','or','that','the','this','to','was','what','when','where','who','will','with','und','the','www');
$string = preg_replace('/\s\s+/i', '', $string); // replace whitespace
$string = trim($string); // trim the string
$string = preg_replace('/[^a-zA-Z0-9 -]/', '', $string); // only take alphanumerical characters, but keep the spaces and dashes too…
$string = strtolower($string); // make it lowercase
preg_match_all('/\b.*?\b/i', $string, $matchWords);
$matchWords = $matchWords[0];
foreach ( $matchWords as $key=>$item ) {
if ( $item == '' || in_array(strtolower($item), $stopWords) || strlen($item) <= 3 ) {
unset($matchWords[$key]);
}
}
$wordCountArr = array();
if ( is_array($matchWords) ) {
foreach ( $matchWords as $key => $val ) {
$val = strtolower($val);
if ( isset($wordCountArr[$val]) ) {
$wordCountArr[$val]++;
} else {
$wordCountArr[$val] = 1;
}
}
}
arsort($wordCountArr);
$wordCountArr = array_slice($wordCountArr, 0, 10);
return $wordCountArr;
}
Please help :(
You should make simple changes:
replace stopwords in $stopWords array with proper Bengali stopwords
remove this string $string = preg_replace('/[^a-zA-Z0-9 -]/', '', $string); because Bengali sybmols doesn't match this pattern
Full code looks like:
<?php
function extractCommonWords($string){
// replace array below with proper Bengali stopwords
$stopWords = array('i','a','about','an','and','are','as','at','be','by','com','de','en','for','from','how','in','is','it','la','of','on','or','that','the','this','to','was','what','when','where','who','will','with','und','the','www');
$string = preg_replace('/\s\s+/i', '', $string); // replace whitespace
$string = trim($string); // trim the string
// remove this preg_replace because Bengali sybmols doesn't match this pattern
// $string = preg_replace('/[^a-zA-Z0-9 -]/', '', $string); // only take alphanumerical characters, but keep the spaces and dashes too…
$string = strtolower($string); // make it lowercase
preg_match_all('/\s.*?\s/i', $string, $matchWords);
$matchWords = $matchWords[0];
foreach ( $matchWords as $key=>$item ) {
if ( $item == '' || in_array(strtolower(trim($item)), $stopWords) || strlen($item) <= 3 ) {
unset($matchWords[$key]);
}
}
$wordCountArr = array();
if ( is_array($matchWords) ) {
foreach ( $matchWords as $key => $val ) {
$val = trim(strtolower($val));
if ( isset($wordCountArr[$val]) ) {
$wordCountArr[$val]++;
} else {
$wordCountArr[$val] = 1;
}
}
}
arsort($wordCountArr);
$wordCountArr = array_slice($wordCountArr, 0, 10);
return $wordCountArr;
}
$string = <<<EOF
টিপ বোঝে না, টোপ বোঝে না টিপ বোঝে না, কেমন বাপু লোক
EOF;
var_dump(extractCommonWords($string), $string);
Output will be:
array(4) {
["বোঝে"]=>
int(2)
["টোপ"]=>
int(1)
["না"]=>
int(1)
["কেমন"]=>
int(1)
}
string(127) "টিপ বোঝে না, টোপ বোঝে না টিপ বোঝে না, কেমন বাপু লোক"

Warning : Illegal offset type error

I'm getting "illegal offset type" error for line $wordCountArr[$val]['bytotal'] = $wordCountArr[$val]['count'] / $totalWords; of this code. Here's the code in case anyone can help:
<?php
function extractCommonWords($string)
{
$stopWords = array('i','a','about','an','and','are','as','at','be','by','com','de','en','for','from','how','in','is','it','la','of','on','or','that','the','this','to','was','what','when','where','who','will','with','und','the','www');
$string = preg_replace('/ss+/i', '', $string);
$string = trim($string); // trim the string
$string = preg_replace('/[^a-zA-Z0-9 -]/', '', $string); // only take alphanumerical characters, but keep the spaces and dashes too…
$string = strtolower($string); // make it lowercase
preg_match_all('/\b.*?\b/i', $string, $matchWords);
$matchWords = $matchWords[0];
$totalWords = count($matchWords[0]);
foreach ( $matchWords as $key=>$item ) {
if ( $item == '' || in_array(strtolower($item), $stopWords) || strlen($item) <= 3 ) {
unset($matchWords[$key]);
}
}
$wordCountArr = array();
if ( is_array($matchWords) ) {
foreach ( $matchWords as $key => $val ) {
$val = strtolower($val);
if ( !isset($wordCountArr[$val])) {
$wordCountArr[$val] = array();
}
if ( isset($wordCountArr[$val]['count']) ) {
$wordCountArr[$val]['count']++;
} else {
$wordCountArr[$val]['count'] = 1;
}
}
arsort($wordCountArr);
$wordCountArr = array_slice($wordCountArr, 0, 10);
foreach ( $wordCountArr as $key => $val) {
$wordCountArr[$val]['bytotal'] = $wordCountArr[$val]['count'] / $totalWords;
}
}
return $wordCountArr;
}
$text = "AES algo to encrypt files.";
$words = extractCommonWords($text);
echo implode(',', array_keys($words));
?>
Look your entire foreach loop:
Change the variable $wordCountArr to $val:
foreach ( $wordCountArr as $key => $val) {
$val['bytotal'] = $val['count'] / $totalWords;
}
Hope it helps you.
You should be using $key not $val in your final foreach loop.
foreach ( $wordCountArr as $key => $val) {
$wordCountArr[$key]['bytotal'] = $wordCountArr[$key]['count'] / $totalWords;
}

Categories