I have the following regular expression:
preg_match_all("/.{0,40}<b>(.+?)<\/b>.{0,40}/i", $string, $matches);
Currently as it is, it grabs 40 characters before the bold, and 40 characters after the bold. What can I do to change it from characters to words. How can I get is so it gets 20 words before the bold and 20 words after the bold?
Here is an example snippet of a string:
Tags are add by using either the keyword "in" or "<b>tagged</b>". Spiderman This will find all results containing
$str0 = 'Tags are add by using either the keyword "in" or "<b>tagged</b>". Spiderman This will find all results containing';
$len0 = strlen($str0);
preg_match_all('/<b>.+?<\/b>/i', $str0, $matches);
$str1 = $matches[0][0];
$len1 = strlen($str1);
$len2 = strpos($str0, $matches[0][0]);
$str2 = substr($str0, 0, $len2);
$len3 = $len0 - $len1 - $len2;
$str3 = substr($str0, $len1+$len2, $len3);
$arr1 = array_reverse(explode(' ', $str2));
$arr2 = explode(' ', $str3);
$key1 = count($arr1) - 1;
$key2 = count($arr2) - 1;
$i = 0;
$before = array();
while($i < $key1 && count($before) < 20) {
if (preg_match('/\w/', $arr1[$i])) {
$before[] = $arr1[$i];
}
$i++;
}
$i = 0;
$after = array();
while($i < $key2 && count($after) < 20) {
if (preg_match('/\w/', $arr2[$i])) {
$after[] = $arr2[$i];
}
$i++;
}
var_dump($before);
var_dump($after);
Although it is kinda long code, but it really works:
array:before (size=9)
0 => string 'or' (length=2)
1 => string '"in"' (length=4)
2 => string 'keyword' (length=7)
3 => string 'the' (length=3)
4 => string 'either' (length=6)
5 => string 'using' (length=5)
6 => string 'by' (length=2)
7 => string 'add' (length=3)
8 => string 'are' (length=3)
array:after (size=6)
0 => string 'Spiderman' (length=9)
1 => string 'This' (length=4)
2 => string 'will' (length=4)
3 => string 'find' (length=4)
4 => string 'all' (length=3)
5 => string 'results' (length=7)
Try this to get 20 words before and after bold.
/(?:[^\s]+\s){0,20}<b>(.+?)<\/b>(?:[^\s]+\s){0,20}/i
Related
Rearrange words in Array based on position of the first array. In my code there are two array my first array is the base array from which i am going to compare it with second array and make the position same as first array.
Consider 2 input
By considering 1 input as base i am applying levenshtein(metaphone(each word database),metaphone(each word of bank)) then based on that arranging the words of bankdata in new array
databaseName = LAL BAHADUR SHASTRI
bankdata = SHASTRI LAL
source code will only rearrange bankdata and stored in in new array
current output of bankdata : LAL SHASTRI
Rearrangement is happening properly just need to arrange words in array
$db = 'LAL BAHADUR SHASTRI YADAV';
$bank = 'SHASTRI LAL';
$a = reArrangeArray($db,$bank);
function reArrangeArray($db,$bank)
{
$dataBaseName = $db;
$bankdataRows = [$db,$bank,];
$dbWords = preg_split("#[\s]+#", $dataBaseName);
foreach ($bankdataRows as $bankdata)
{
$bankWords = preg_split("#[\s]+#", trim($bankdata));
$result = [];
if(!empty($bankWords))
foreach ($dbWords as $dbWord)
{
$idx = null;
$least = PHP_INT_MAX;
foreach ($bankWords as $k => $bankWord)
if (($lv = levenshtein(metaphone($bankWord),metaphone($dbWord))) < $least)
{
$least = $lv;
$idx = $k;
}
#$result[] = $bankWords[$idx];
unset($bankWords[$idx]);
}
$result = array_merge($result, $bankWords);
var_dump($result);
}
}
Case 1:
CURRENT OUTPUT
array (size=4)
0 => string 'LAL' (length=3)
1 => string 'BAHADUR' (length=7)
2 => string 'SHASTRI' (length=7)
3 => string 'YADAV' (length=5)
array (size=4)
0 => string 'LAL' (length=3)
1 => string 'SHASTRI' (length=7)
2 => null
3 => null
Expected Output
I need array position as same as databaseArray
$dbName = 'LAL BAHADUR SHASTRI YADAV';
$bankName = 'SHASTRI LAL';
array of db (size=4)
0 => string 'LAL' (length=3)
1 => string 'BAHADUR' (length=7)
2 => string 'SHASTRI' (length=7)
3 => string 'YADAV' (length=5)
array of bankname (size=4)
0 => string 'LAL' (length=3)
1 => #
2 => string 'SHASTRI' (length=7)
3 => ###
if word not found in first array it should be place with # since position is 3 which dont have matching element it has 3 #
Case 2
Input :
$dbName = NikithaRani MohanRao
$bankdata = Nikitha Rani Mohan Rao
Output :
$newbankdata = NikithaRani MohanRao
It should concatenate the word if found concatenated in $dbName
<?php
$DatabaseName = "LAL BAHADUR SHASTRI YADAV";
$BankName = "SHASTRI LAL";
$data = explode(" ", $DatabaseName);
$bank = explode(" ", $BankName);
sort($data);
sort($bank);
if($data == $bank){
echo "true";
exit;
}
$lev = 0;
foreach($data as $key => $name){
$lev += levenshtein($name, $bank[$key]);
}
echo PHP_EOL . $lev;
?>
I have a String in this format
{value=very big +$5},{value=super big +$10},{value=extra big +$15}
How to convert them into 2 Arrays in such format?
For example:
$name=["very big","super big","extra big"];
$price=["5","10","15"]; // OR $price=[5,10,15];
I can do that by using explode() if the string format is in a simpler format. However, this format is too complicated. Anyone knows how to do that ?
use explode with ',' ,'=' ,'+$'
$string = "{value=very big +$5},{value=super big +$10},{value=extra big +$15}";
$temp_array = (explode(",",$string));
foreach($temp_array as $val)
{
$temp_array = (explode("=",$val));
$temp_string = $temp_array[1];
$temp_string = str_replace("}","",$temp_string);
$temp_array = (explode("+$",$temp_string));
$name[] = $temp_array[0];
$price[] = $temp_array[1];
}
DEMO
You may try it like the Snippet below suggests. Quick-Test: Here.
<?php
$string = '{value=very big +$5},{value=super big +$10},{value=extra big +$15}';
$arrParts = explode(',', $string);
$name = [];
$price = [];
$result = [];
foreach($arrParts as $iKey=>$part){
$block = preg_replace(["#^\{.*?=#", "#\}$#"], "", $part);
$segments = preg_split("#\s#", $block); //<== CREATE AN ARRAY WITH 3 COLUMNS
list($val1, $val2, $val3) = $segments;
$namePart = $val1 . " {$val2}";
$pricePart = preg_replace("#[\+\-\$]#", "",$val3);
$name[] = $namePart;
$price[] = $pricePart;
// BONUS: JUST CREATE A 3RD ARRAY WITH NAMED-KEY
$result[$namePart] = $pricePart;
}
var_dump($name);
//YIELDS::
array (size=3)
0 => string 'very big' (length=8)
1 => string 'super big' (length=9)
2 => string 'extra big' (length=9)
var_dump($price);
//YIELDS::
array (size=3)
0 => string '5' (length=1)
1 => string '10' (length=2)
2 => string '15' (length=2)
var_dump($result);
//YIELDS::
array (size=3)
'very big' => string '5' (length=1)
'super big' => string '10' (length=2)
'extra big' => string '15' (length=2)
You can use regex, for example this should work:
preg_match_all('/value=([\w\s]+)\s\+/', $string, $matches)
preg_match_all('/\$([\d]+)\}/', $string, $matches)
I am making a function that can help me to cast the string to array, but that strange when the function always add first character to the array. Thank at first and this is code i used in function:
$string = '0:009987;1:12312;2:45231;3:00985;3:10923;4:11253;4:62341;4:01102;4:58710;4:10102;4:87093;4:12034;5:9801;6:1092;6:4305;6:1090;7:450;8:34';
$explodedString = explode(';', $string);
//var_dump($explodedString);
$takeArray = array();
$counti = 0;
foreach($explodedString as $exploded){
$secondExp = explode(':', $exploded);
var_dump($secondExp);
if(isset($takeArray[$secondExp[0]])){
$takeArray[$secondExp[0]][$counti] = $secondExp[1];
}else{
$takeArray[$secondExp[0]] = $secondExp[1];
}
$counti++;
}
var_dump($takeArray);
This is current output of this code:
array (size=9)
0 => string '009987' (length=6)
1 => string '12312' (length=5)
2 => string '45231' (length=5)
3 => string '00981' (length=5)
4 => string '11253 605181' (length=12)
5 => string '9801' (length=4)
6 => string '1092 41' (length=16)
7 => string '450' (length=3)
8 => string '34' (length=2)
Looking into row 4 you will see the string: '605181', this string come from the first character of each value belong to 4. But i need an output array like this:
[0] => {'009987'},
....
[4] => { '11253', '62341', ...., },
....
Please help me.
I'm not sure why you need $counti. All you need to do is, initialize the $takeArray[$n] if it doesn't exists, and push a new value to it. Something like this:
if(!isset($takeArray[$secondExp[0]])) {
// Initialize the array
$takeArray[$secondExp[0]] = array();
}
// Push the new value to the array
$takeArray[$secondExp[0]][] = $secondExp[1];
You only need to do the following :
$takeArray = array();
foreach($explodedString as $exploded) {
$secondExp = explode(':', $exploded);
$takeArray[(int)$secondExp[0]][] = $secondExp[1];
}
$string = '0:009987;1:12312;2:45231;3:00985;3:10923;4:11253;4:62341;4:01102;4:58710;4:10102;4:87093;4:12034;5:9801;6:1092;6:4305;6:1090;7:450;8:34';
$explodedString = explode(';', $string);
$takeArray = array();
foreach($explodedString as $exploded)
{
$secondExp = explode(':', $exploded);
$takeArray[$secondExp[0]][] = $secondExp[1];
}
var_dump($takeArray);
I have strings like the following that I have to split:
Other,CODSITE,Items::getCodCdeCli+Address::getNameAddress
Other,CODSITE,Items::getCodCdeCli
Items::getCode+Address::getName,CODSITE+Items::getSample,Items::getItemID
Other, CODSITE, CODSITE2
Into:
array(
array(
0 => 'Other',
1 => 'CODSITE',
2 => array(
'Items' => 'getCodCdeCli',
'Address' => 'getNameAddress'
)
),
//...
)
Each comma involve new information, if we have a '+' we need to append both data. If we have '::' we need to get first part as key of the result information.
For beginning this solution I have tried to split this on comma:
$re = "/([^,]+)/";
$str = "Other,CODSITE,Items::getCodCdeCli+Address::getNameAddress";
preg_match_all($re, $str, $matches);
for now with this regex I have this:
array (size=2)
0 =>
array (size=3)
0 => string 'Other' (length=5)
1 => string 'CODSITE' (length=7)
2 => string 'Items::getCodCdeCli+Address::getNameAddress' (length=43)
1 =>
array (size=3)
0 => string 'Other' (length=5)
1 => string 'CODSITE' (length=7)
2 => string 'Items::getCodCdeCli+Address::getNameAddress' (length=43)
Which is wrong. I have same result twice.. and line 2 => [...] is not split (which is normal with my regex)
One way of doing it in single pass is by using array_combine function like this:
$str = 'Other,CODSITE,Items::getCodCdeCli+Address::getNameAddress';
if ( preg_match_all('~(?|[,+]([^,+]+)::([^,+]+)|([^,]+))~', $str, $m) )
print_r( array_combine ( $m[1], $m[2] ) );
Output:
Array
(
[Other] =>
[CODSITE] =>
[Items] => getCodCdeCli
[Address] => getNameAddress
)
Does it need to be regex? It might be possible to achieve this with a couple of explodes and foreach loops:
$str = 'Other,CODSITE,Items::getCodCdeCli+Address::getNameAddress';
//new entry per comma (,)
$results = explode(',',$str);
//check each entry for array information
foreach($results as &$result) {
if(strpos($result,'+') !== FALSE) {
//explode array information
$bits1 = explode('+',$result);
$result = array();
foreach($bits1 as &$subresult) {
//format array information into key => value pairs
if(strpos($subresult,'::') !== FALSE) {
$bits = explode('::',$subresult);
$result[$bits[0]] = $bits[1];
}
}
}
}
var_dump($results);
/**
* array (size=3)
* 0 => string 'Other' (length=5)
* 1 => string 'CODSITE' (length=7)
* 2 => array (size=2)
* 'Items' => string 'getCodCdeCli' (length=12)
* 'Address' => string 'getNameAddress' (length=14)
*/
With the help of #Richard Parnaby-King answer. This is the solution, in fact no regex is needed even if i'm sure we can use it for the same result.
$lines = array(
0 => 'Other,CODSITE,Items::getCodCdeCli+Address::getNameAddress',
2 => 'Other,CODSITE,Items::getCodCdeCli',
3 => 'Items::getCode+Address::getName,CODSITE+Items::getSample,Items::getItemID',
4 => 'Other, CODSITE, CODSITE2',
);
foreach ($lines as $input) {
$informations = explode(',', $input);
$result = array();
foreach ($informations as $information) {
if(strpos($information, '+') !== FALSE) {
$classes = explode('+',$information);
$temp = array();
foreach($classes as $subresult) {
if(strpos($subresult,'::') !== FALSE) {
$classAndMethod = explode('::',$subresult);
$temp[$classAndMethod[0]] = $classAndMethod[1];
} else {
$temp[] = trim($subresult);
}
}
$result[] = $temp;
} elseif (strpos($information, '::') !== FALSE) {
$classAndMethod = explode('::',$information);
$result[][$classAndMethod[0]] = $classAndMethod[1];
} else {
$result[] = trim($information);
}
}
var_dump($result);
}
It works !
In my project, i will have to receive a string from user (in textarea). Now this string will be converted into array. Now the problem is that, the character length must be minimum of 3,
in the following array next element should be joined to current one if character length is less than 3. How to perform it in PHP.
a[0]=>this a[1]=>is a[2]=>an a[3]=>example a[4]=>array.
Output should be:
a[0]=>this a[1]=>isan a[2]=>example a[3]=>array.
Just try with:
$input = ['this', 'is', 'an', 'example', 'array.'];
$output = [];
$part = '';
foreach ($input as $value) {
$part .= $value;
if (strlen($part) > 3) {
$output[] = $part;
$part = '';
}
}
Output:
array (size=4)
0 => string 'this' (length=4)
1 => string 'isan' (length=4)
2 => string 'example' (length=7)
3 => string 'array.' (length=6)