I hope you can help me.
I have a string like the following
Luke 1:26-38
And I would like to be able to break it up into tokens or individual variables so that I can use the variables in an SQL query.
I've tried using explode, however I've only been able to make it explode on one character such as : or -
My string has : and - and also a space between the name and the first number.
My goal is to have:
$name = Luke;
$book = 1;
$from = 26;
$to = 38;
Is anyone able to help please.
Many thanks
You can do that with a simple string scanning (Demo):
$r = sscanf("Luke 1:26-38", "%s %d:%d-%d", $name, $book, $from, $to);
The varibales then contain the information. %s represents a string (without spaces), %d a decimal. See sscanf.
To make this "bible safe", it needs some additional modifications:
$r = sscanf($string, "%[ a-zA-Z] %d:%d-%d", $name, $book, $from, $to);
$name = trim($name);
(Second demo).
list( $name, $book, $from, $to ) = preg_split( '/[ :-]/', 'Luke 1:26-38' );
echo $name; //"Luke"
/* Split results in an Array
(
[0] => Luke
[1] => 1
[2] => 26
[3] => 38
)
*/
$string = "Luke 1:26-38";
preg_match('#^(\w+)\s(\d+):(\d+)-(\d+)$#', $string, $result);
print_r($result);
regex is hard to configure for this because of the multiple configurations of bible book names, chapter and verse num. Because some books begin with a number and some books have multiple spaces in the book names.
I came up with this for building a sql query, it works for these passage search types..
(John), (John 3), (Joh 3:16), (1 Thes 1:1)
Book names can be 3 letter abbreviations.
Does unlimited individual word search and exact phrase.
$string = $_GET['sstring'];
$type = $_GET['stype'];
switch ($type){
case "passage":
$book = "";
$chap = "";
$stringarray = explode(':', $string); // Split string at verse refrence/s, if exist.
$vref = $stringarray[1];
$vrefsplit = explode('-', $vref);// Split verse refrence range, if exist.
$minv = $vrefsplit[0];
$maxv = $vrefsplit[1]; // Assign min/max verses.
$bc = explode(" ", $stringarray[0]); // Split book string into array with space as delimiter.
if(is_numeric($bc[count($bc)-1])){ // If last book array element is numeric?
$chap = array_pop($bc); // Remove it from array and assign it to chapter.
$book = implode(" ", $bc); // Put remaining elemts back into string and assign to book.
}else{
$book = implode(" ", $bc); // Else book array is just book, convert back to string.
}
// Build the sql query.
$query_rs1 = "SELECT * FROM kjvbible WHERE bookname LIKE '$book%'";
if($chap != ""){
$query_rs1.= " AND chapternum='$chap'";
}
if($maxv != ""){
$query_rs1.= " AND versenum BETWEEN '$minv' AND '$maxv'";
}else if($minv != ""){
$query_rs1.= " AND versenum='$minv'";
}
break;
case "words":
$stringarray = explode(" ", $string); // Split string into array.<br />
// Build the sql query.
$query_rs1 = "SELECT * FROM kjvbible WHERE versetext REGEXP '[[:<:]]". $stringarray[0] ."[[:>:]]'";
if(count($stringarray)>1){
for($i=1;$i<count($stringarray);$i++){
$query_rs1.= " AND versetext REGEXP '[[:<:]]". $stringarray[$i] ."[[:>:]]'";
}
}
break;
case "xphrase":
// Build the sql query.
$query_rs1 = "SELECT * FROM kjvbible WHERE versetext REGEXP '[[:<:]]". $string ."[[:>:]]'";
break;
default :
break;
}
Related
I have a code in php it takes a well formatted string such as 'field,operator,value' and produces a WHERE statement to MySQL database query.
if the two fields names below end with the same characters such as '*id' such as 'id' and 'classid' it produces strange behavior. such as the following:
$where = $_GET['where'];
$tokens = multiexplode(array("^", "~", "(", ")"), $where);
$where = str_replace("^", " AND ", $where);
foreach ($tokens as $item) {
if (!empty($item)) {
$where = str_replace($item, getOperand($item), $where);
}
}
echo 'WHERE '.$where;
function multiexplode($delimiters, $string)
{
$unifydelimters = str_replace($delimiters, $delimiters[0], $string);
$conditions = explode($delimiters[0], $unifydelimters);
return $conditions;
}
function getOperand($item)
{
$extokens = explode (",", $item);
switch (trim($extokens[1])) {
case 'eq':
return trim($extokens[0]) . " = '" . trim($extokens[2]) . "' ";
break;
default:
return "";
break;
}
}
tested with :
http://localhost/test/test.php?where=id,eq,1^classid,eq,19
ALways show: id = '1' AND classid='1' 9
Not: id = '1' AND classid='19'
But if any other field ends differently from the other such as:
http://localhost/test/test.php?where=id,eq,1^class,eq,19
It correctly shows: id = '1' AND class='19'
Any idea why this is happening??
Thanks,
The problem is that when you search for the first expression id,eq,1 for the replacement in the string
id,eq,1^classid,eq,19
You will find two positions:
id,eq,1^classid,eq,19
^ ^
id,eq,1 |
id,eq,1
This means you will do two replacements, even though you wanted only replace one.
To solve this problem you don't need to work with the original input string $where. Instead you can use the already create array in $tokens and change the individual array elements. You can use array_map() to do that, like this:
$changed = array_map('getOperand', $tokens);
Then you can put the array together to a string with ' AND ' as the separator:
$result = implode(' AND ', $changed);
This will finally generate the following result:
id = '1' AND classid = '19'
Keep in mind that you should use prepared statements to avoid SQL injections, see How can I prevent SQL injection in PHP?
This question already has answers here:
How to split a long string without breaking words?
(4 answers)
Closed 7 years ago.
I created a variable which stores a very long string, and I want to print this variable in multiple lines.
$test ="This is some example text , I want to print this variable in 3 lines";
The output of the above $test would be
This is some example text,
I want to print this
variabale in 3 lines
Note: I want a new line after each 15 characters or each line have equal characters. I don't want to add break tag or any other tag during variable assignment.
CODEPAD
<?php
$str= 'This is some example text , I want to print this variable in 3 lines, also.';
$x = '12';
$array = explode( "\n", wordwrap( $str, $x));
var_dump($array);
?>
or use
$array = wordwrap( $str, $x, "\n");
Try this
<?php
$test ="This is some example text , I want to print this variable in 3 lines";
$array = str_split($test, 10);
echo implode("<br>",$array);
Based on this link
PHP: split a long string without breaking words
$longString = 'I like apple. You like oranges. We like fruit. I like meat, also.';
$arrayWords = explode(' ', $longString);
// Max size of each line
$maxLineLength = 18;
// Auxiliar counters, foreach will use them
$currentLength = 0;
$index = 0;
foreach($arrayWords as $word)
{
// +1 because the word will receive back the space in the end that it loses in explode()
$wordLength = strlen($word) + 1;
if( ( $currentLength + $wordLength ) <= $maxLineLength )
{
$arrayOutput[$index] .= $word . ' ';
$currentLength += $wordLength;
}
else
{
$index += 1;
$currentLength = $wordLength;
$arrayOutput[$index] = $word;
}
}
The easiest solution is to use wordwrap(), and explode() on the new line, like so:
$array = explode( "\n", wordwrap( $str, $x));
Where $x is a number of characters to wrap the string on.
Copied from here last comment
Try This
<?php
$test ="This is some example text , I want to print this variable in 3 lines";
$explode=explode(" ",$test);
$String='';
$newString='';
$maxCharacterCount=23;
foreach ($explode as $key => $value) {
$strlen=strlen($String);
if($strlen<=$maxCharacterCount){
$String.=' '.$value;
}else{
$newString.=$String.' '.$value.'<br>';
$String='';
}
}
$finalString= $newString.$String;
echo $finalString;
?>
OK now all is working. You just pass $string and #maxlenght in characters number and function returns table with cutted string.
don`t cut words,
don`t ever exeed maxLenght,
Only one thing to rember is that u need to care for comma usage i.e: "word, word".
$test ="This is some example text, I want to print this variable in 3 lines dasdas das asd asd asd asd asd ad ad";
function breakString($string, $maxLenght) {
//preparing string, getting lenght, max parts number and so on
$string = trim($string, ' ');
$stringLenght = strlen($string);
$parts = ($stringLenght / $maxLenght );
$finalPatrsNumber = ceil($parts);
$arrayString = explode(' ', $string);
//defining variables used to store data into a foreach loop
$partString ='';
$new = array();
$arrayNew = array();
/**
* go througt every word and glue it to a $partstring
*
* check $partstring lenght if it exceded $maxLenght
* then delete last word and pass it again to $partstring
* and create now array value
*/
foreach($arrayString as $word){
$partString.=$word.' ';
while( strlen( $partString ) > $maxLenght) {
$partString = trim($partString, ' ');
$new = explode(' ', $partString);
$partString = '';
$partString.= end($new).' ';
array_pop($new);
//var_dump($new);
if( strlen(implode( $new, ' ' )) < $maxLenght){
$value = implode( $new, ' ' );
$arrayNew[] = $value;
}
}
}
// /**
// * psuh last part of the string into array
// */
$string2 = implode(' ', $arrayNew);
$string2 = trim($string2, ' ');
$string2lenght = strlen($string2);
$newPart = substr($string, $string2lenght);
$arrayNew[] = $newPart;
/**
* return array with broken $parts of $string
* $party max lenght is < $maxlenght
* and breaks are only after words
*/
return $arrayNew;
}
/**
* sample usage
* #param string $string
* #param int $maxLenght Description
*/
foreach( breakString($test, 30) as $line){
echo $line."<br />";
}
displays:
This is some example text, I
want to print this variable
in 3 lines dasdas das asd asd
asd asd asd ad ad
btw. u can easly add here some rules like:
no single char in last row or don`t break on certain words and so on;
In the first time, I'm sorry for my disastrous english.
After three days trying to solve this, i give up.
Giving this array:
$names = array ( "James Walter Case", "Benjamin Wallace Pinkman", "Billy Elliot Newson" )
I have to extract the full name of the higher first stringlength word of each full name.
In this case, considering this condition Benjamin will be the higher name. Once
this name extracted, I have to print the full name.
Any ideas ? Thanks
How about this?
$names = array ( "James Walter Case", "Benjamin Wallace Pinkman", "Billy Elliot Newson" );
if (count($names) > 0)
{
$higher_score = 0;
foreach ($names as $name_key => $name_value)
{
$name_array = explode(" ", $name_value);
// echo("<br><b>name_array -></b><pre><font FACE='arial' size='-1'>"); print_r($name_array); echo("</font></pre><br>");
$first_name = $name_array[0];
// echo "first_name -> ".$first_name."<br>";
$score = strlen($first_name);
// echo "score -> ".$score."<br>";
if ($score > $higher_score)
{
$higher_score = $score;
$winner_key = $name_key; }
}
reset($names);
}
echo("longest first name is ".$names[$winner_key]." with ".$higher_score." letters.");
As said before, you can use array_map to get all the lenghts of the first strings, and then get the name based on the key of that value.
$names = array ( "James Walter Case", "Benjamin Wallace Pinkman", "Billy Elliot Newson" );
$x = array_map(
function ($a) {
$x = explode (" ", $a); // split the string
return strlen($x[0]); // get the first name
}
, $names);
$maxs = array_keys($x, max($x)); // get the max values (may have equals)
echo $names[$maxs[0]]; // get the first max
-- EDIT
Actually, there is a better way of doing this, considering this case. You can simply order the array by the lenght of the first names, and then get the first key:
usort($names,
function ($a, $b) {
$aa = explode(" ", $a); // split full name
$bb = explode(" ", $b); // split full name
if (strlen($aa[0]) > strlen($bb[0])){
return 0; // if a > b, return 0
} else {
return 1; // else return 1
}
}
);
echo $names[0]; // get top element
Allow me to provide a handmade solution.
<?php
$maxLength = 0;
$fullName = "";
$parts = array();
foreach($names as $name){
/* Exploding the name into parts.
* For instance, "James Walter Case" results in the following array :
* array("James", "Walter", "Case") */
$parts = explode(' ', $name);
if(strlen($parts[0]) > $maxLength){ // Compare first length to the maximum.
$maxLength = strlen($parts[0]);
$fullName = $name;
}
}
echo "Longest first name belongs to " . $fullName . " (" . $maxLength . " character(s))";
?>
Basically, we iterate over the array, split each name into parts (delimited by spaces), and try to find the maximum length among first parts of names ($parts[0]). This is basically a maximum search algorithm.
There may be better ways with PHP array_* functions, but well, this one gets pretty self-explanatory.
You can try something like..
$maxWordLength=0;
$maxWordIndex=null;
foreach ($names as $index=>$name){
$firstName=first(explode(' ',$name));
if (strlen($firstName)>maxWordLength){
$maxWordLength=strlen($firstName);
$maxWordIndex=$index;
}
}
if ($maxWordIndex){
echo $names[$maxWordIndex];
}
I have a sting that looks like this
$storelist = "‘F Mart (6)’, ‘ACME (5)’, 'J/M Store (17)'";
I want to break out selected companies and the number of locations by comparing the first string to a second string like
$selectedstores = "‘F Mart’, 'J/M Store";
And output a sting like
$selectedwithnumber = "‘F Mart (6)’, 'J/M Store (17)'"
There could be 1 to 15 companies in a string and the location number varies but the apostrophes and parenthesis are standard. I hope there an easy way to do this as I have no idea where to start. Thanks in advance.
You can use explode function to split arrays to parts, and use preg_replace function to remove number of companies (with brackets) from first string. below you can find working example:
$storelist = "‘F Mart (6)’, ‘ACME (5)’, 'J/M Store (17)'";
$selectedstores = "‘F Mart’, 'J/M Store'";
//split second array
$selectedArray = explode(', ', $selectedstores);
$resultArray = array();
//split first array
foreach(explode(', ', $storelist) as $storeWithNumber) {
//remove " (number)" from each part
$store = preg_replace('/\s+\(\d+\)/', '', $storeWithNumber);
//check if current part is on selected list
if (in_array($store, $selectedArray)) {
$resultArray[] = $storeWithNumber;
}
}
$selectedwithnumber = implode(', ', $resultArray);
echo $selectedwithnumber.PHP_EOL;
result is:
‘F Mart (6)’, 'J/M Store (17)'
This will get what you need based on your description. It breaks up your strings into arrays and then uses a nested foreach loop to do the comparisons. I used string functions over regular expression functions in case speed becomes an issue. It does however require that your main string of stores follows the conventions you described.
<?php
$storelist = "'F Mart (6)', 'ACME (5)', 'J/M Store (17)'";
$selectedstores = "'F Mart', 'J/M Store'";
$stores = explode(",", $storelist);
$selected = explode(",", $selectedstores);
$newStoreList = array();
foreach($selected as $selectedStore) {
foreach($stores as $store) {
$s = trim( $selectedStore, "' ");
if(strstr($store, $s)) {
$newStoreList[] = $store;
}
}
}
$newStoreList = implode(",", $newStoreList);
echo $newStoreList;
?>
This will output: 'F Mart (6)', 'J/M Store (17)'
Hope that helps!
This php function retrieves a list of common words used in a string and excludes a blacklist of words.
Array1: a,b,c
Although a default blacklist is useful, I needed to add words to the blacklist from a database.
Array2: d,e,f
I added the MYSQL which gets an additional list from an field in our services table.
I explode \n from the words into an array and merge the two arrays at the beginning of the function so that the blacklist is now
Array3: a,b,c,d,e,f
To test I used print_r to display the array and it does merge successfully.
The problem is this...
If I manually add d,e,f to the default array the script returns a clean list of words.
If I merge the two arrays into one its returning the list of words with the blacklist words still in it.
Why would the merged array be any different than just adding to the default array?
Here is the function
function extractCommonWords($string,$init_blacklist){
/// the default blacklist words
$stopWords = array('a','b','c');
/// select the additional blacklist words from the database
$gettingblack_sql = "SELECT g_serv_blacklist FROM services WHERE g_serv_id='".$init_blacklist."' LIMIT 1";
$gettingblack_result = mysql_query($gettingblack_sql) or die(mysql_error());
$gettingblack_row = mysql_fetch_array($gettingblack_result);
$removingblack_array = explode("\n", $gettingblack_row["g_serv_blacklist"]);
// this adds the d,e,f array from the database to the default a,b,c blacklist
$stopWords = array_merge($stopWords,$removingblack_array);
// replace whitespace
$string = preg_replace('/\s\s+/i', '', $string);
$string = trim($string);
// only take alphanumerical chars, but keep the spaces and dashes too
$string = preg_replace('/[^a-zA-Z0-9 -]/', '', $string);
// make it lowercase
$string = strtolower($string);
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, 30);
return $wordCountArr;
}
/// end of function
/// posted string = a b c d e f g
$generate = $_POST["generate"];
/// the unique id of the row to retrieve additional blacklist keywords from
$generate_id = $_POST["generate_id"];
/// run the function by passing the text string and the id
$generate = extractCommonWords($generate, $generate_id);
/// update the database with the result
$update_data = "UPDATE services SET
g_serv_tags='".implode(',', array_keys($generate))."'
WHERE g_serv_acct='".$_SESSION["session_id"]."'
AND g_serv_id='".$generate_id."' LIMIT 1";
$update_result = mysql_query($update_data);
if(!$update_result){die('Invalid query:' . mysql_error());}
else{echo str_replace(",",", ",implode(',', array_keys($generate)));}
/// end of database update
If the extra blacklist in the database was populated in an admin panel from a Windows client, there is likely to be a stray \r at the end of each word. Thus, your list would be a,b,c,d\r,e\r,f\r.
Try replacing this line:
$removingblack_array = explode("\n", $gettingblack_row["g_serv_blacklist"]);
with this:
$removingblack_array = preg_split('/(\r|\n|\r\n)/', $gettingblack_row["g_serv_blacklist"]);