I want to know is there any way to split text like this:
123456789 into 123-456-789
as to add "-" after every 3 characters?
Just wanted to know, as I know the reverse, but how to do this is over my head. ;)
and also if the text is
ABCDEFGHI OR A1B2C3D4E or any other format
without any space between the characters !
language: PHP only
<?php
$i = '123456789';
echo 'result: ', wordwrap($i, 3, '-', true);printsresult: 123-456-789
see http://php.net/wordwrap
I'm not a big fan of regexes for simple string extraction (especially fixed length extractions), preferring them for slightly more complex stuff. Almost every language has a substring function so, presuming your input has already been validated, a simple (pseudo-code since you haven't specified a language):
s = substring (s,0,3) + "-" + substring (s,3,3) + "-" + substring (s,6,3)
If you want it every three characters for a variable length string (with odd size at the end):
t = ""
sep = ""
while s != "":
if s.len <= 3:
t = t + sep + s
s = ""
else:
t = t + sep + substring (s,0,3)
s = substring (s,3)
sep = "-"
s = t
For any language:
Create an empty string variable called "result"
Create an integer counter variable, "i", which increments until the length of the original string (the one with the number)
Append each character from the original string to "result"
If i modulo 3 (usually % or mod) is zero, append a dash to "result"
In the interest of completeness, here is a Python solution:
>>> a = "123456789"
>>> a[0:3] + "-" + a[3:6] + "-" + a[6:9]
'123-456-789'
Since you updated your question to specify a PHP solution, this should work:
substr($a, 0, 3) . "-" . substr($a, 3, 3) . "-" . substr($a, 6, 3)
See substr for more information on this function. This will work not only for digits, but for alphabetic characters too.
Yet another Python version:
>>> x="123456789"
>>> out=[x[i:i+3] for i in xrange(0, len(x), 3)]
>>> print "-".join(out)
123-456-789
I think that this can be sanely done in a regex with lookahead:
s/(.{3})(?=.)/$1-/g
Since you mentioned PHP in a comment:
preg_replace ("/(.{3})(?=.)/", "$1-", $string);
edit: After VolkerK showed wordwrap, I found chunk-split in the documentation:
$new_string = chunk_split ($string, 3, '-');
This has the advantage that it also works when there are spaces in the string (wordwrap would prefer to break at the spaces).
In Perl:
#!/usr/bin/perl
use strict;
use warnings;
my $string = "123456789";
$string =~ /(\d{3})(\d{3})(\d+)/;
print "$1-$2-$3"
You can do it with (among other means) a regular expression match and replace. The exact syntax depends on the tool or programming language you are using. For instance, one way to do it in Perl would be
$a = "123456789";
$a =~ s/(\d{3})/$1-/g;
chop($a);
print $a;
Line 2 replaces every 3 digits for the same 3 digits and a dash. With chop() we delete the trailing dash.
There is another question here. What to do when the string doesn't contain a multiple by 3 amount of digits? If such strings were allowed, then the above snippet would need modification.
Also, depending on the specifics of the case, you might get away with simple substring replacement, or string slicing.
One more Perl example. This doesn't remove final groups smaller than three, and it leaves initial groups of less than three digits alone. It's based (pretty shamelessly) on the "money numbers" example in Learning Perl (page 212 of the 5th ed):
#!/usr/bin/env perl
use strict;
use warnings;
print "Gimme' a number: ";
chomp(my $number = <STDIN>);
1 while ($number =~ s/([0-9]{3})([0-9]+)/$1-$2/);
print "Now it's $number\n";
Related
I have a data of phone number starts with +63 and 09
for example the user insert 09123456789 then save. The user shouldn't success if he enters +639123456789 because it was same number at all.
I tried using substr_replace
$data3 = substr_replace("+63", "0",0, 3);
is there other option? i think the substr_replace will have error in the future.
thanks
If the +63 must be at the start, you may use a preg_replace like
$s = preg_replace('~^\+63~', '0', $s);
Here,
^ - start of a string position
\+ - a literal +
63 - a 63 substring.
See the regex demo and a PHP demo.
Please also consider Tpojka's suggestion to use a combination of intl-tel-input on front-end and libphonenumber-for-php on back-end if you need to sanitize and validate international phone numbers.
In this case you can have a condition to check and have str_replace
if there is a + on your request then make remove the first 3 letters including +
if (substr($phone, 0, 1) == '+') {
$phone = str_replace(substr($phone, 0, 3), '0', $phone);
}
$phone_number = $phone;
Using PHP I sometimes have strings that look like the following:
111
110
011
1111
0110012
What is the most efficient way (preferably without regex) to determine if a string contains any character other then the character 1?
Here's a one-line code solution that can be put into a conditional etc.:
strlen(str_replace('1','',$mystring))==0
It strips out the "1"s and sees if there's anything left.
User Don't Panic commented that str_replace could be replaced by trim:
strlen(trim($mystring, '1'))==0
which removes leading and trailing 1s and sees if there's anything left. This would work for the particular case in OP's request but the first option will also tell you how many non-"1" characters you have (if that information matters). Depending on implementation, trim might run slightly faster because PHP doesn't have to check any characters between the first and last non-"1" characters.
You could also use a string like a character array and iterate through from the beginning until you find a character which is not =='1' (in which case, return true) or reach the end of the array (in which case, return false).
Finally, though OP here said "preferably without regex," others open to regexes might use one:
preg_match("/[^1]/", $mystring)==1
Another way to do it:
if (base_convert($string, 2, 2) === $string) {
// $string has only 0 and 1 characters.
}
since your $string is basically a binary number, you can check it with base_convert.
How it works:
var_dump(base_convert('110', 2, 2)); // 110
var_dump(base_convert('11503', 2, 2)); // 110
var_dump(base_convert('9111111111111111111110009', 2, 2)); // 11111111111111111111000
If the returned value of base_convert is different from the input, there're something other characters, beside 0 and 1.
If you want checks if the string has only 1 characters:
if(array_sum(str_split($string)) === strlen($string)) {
// $string has only 1 characters.
}
You retrieve all the single numbers with str_split, and sum them with array_sum. If the result isn't the same as the length of the string, then you've other number in the string beside 1.
Another option is treat string like array of symbols and check for something that is not 1. If it is - break for loop:
for ($i = 0; $i < strlen($mystring); $i++) {
if ($mystring[$i] != '1') {
echo 'FOUND!';
break;
}
}
I have a string, something like this:
$str ="it is a test string.";
// for more clarification
i t i s a t e s t s t r i n g .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Now I need to check all characters that are multiples of 4 (plus first character). like these:
1 => i
4 => i
8 => [space]
12 => t
16 => r
20 => .
Now, I need to compare them with Y (Y is a variable (symbol), for example Y = 'r' in here). So I want to replace Y with X (X is a variable (symbol) too, for example X = 'm' in here).
So, I want this output:
it is a test stming.
Here is my solution: I can do that using some PHP function:
strlen($str): to count the number of characters (named $sum)
$sum / 4: To find characters that are multiples of 4
substr($str, 4,1): to select specific character (named $char) {the problem is here}
if ($char == 'r') {}: to compare
str_replace('r','m',$char): to replace
And then combining all $char to each other.
But my solution has two problem:
substr() does not count [space] character (As I mentioned above)
combining characters is complicated a bit. (It needs to some waste processing)
Well, is there any solution? I like to do that using REGEX, Is it possible?
Could just use a simple regex with callback (add u flag if utf-8, s for . to match newline).
$str = preg_replace_callback(['/^./', '/.{3}\K./'], function ($m) {
return $m[0] == "r" ? "m" : $m[0];
}, $str); echo $str;
See this demo at tio.run > it is a test stming.
1st pattern: ^. any first character
2nd pattern: \K resets after .{3} any three characters, only want to check the fourth .
For use with anonymous function PHP >= 5.3 is required. Here is the workaround (demo).
Update: #Mariano demonstrated in his very nice answer that it is even with a single regex replacement possible. Thank you for the benchmark that reveals a rather bad performance for the preg_replace_callback solution. A more efficient variant without callback (but still two patterns).
$str = preg_replace(['/^r/', '/(?:...[^r])*...\Kr/'], 'm', $str);
I also included #revo's answer from 2017 in Mariano's benchmark and ran it on tio.run (100k loops). With newer PHP and PCRE2 the numbers seem to have changed slightly, "no regex" leads at tio.run.
In .NET or modern browser JS regex it also could be done like this by a variable length lookbehind.
If all characters in your string are in single byte, you can use something from PHP's official language reference:
$str ="it is a test string.";
$y="r";
$x="m";
$len=strlen($str);
if($str[0]==$y)
{
$str=substr_replace($str,$x,0,1);
}
if($len>=3)
{
for($i=3;$i<$len;$i+=4)
{
if($str[$i]==$y)
{
$str=substr_replace($str,$x,$i,1);
}
}
}
var_dump($str);
3v4l demo
Outputs it is a test stming.
Edit:
As #Don'tPanic points out, String is mutable using [] operator, so instead of using
$str=substr_replace($str,$x,$i,1);
you can just use
$str[$i]=$x;
This is an alternative using preg_replace()
$y = 'r';
$y = preg_quote($y, '/');
$x = 'M';
$x = preg_quote($x, '/');
$subject = 'rrrrrr rrrrr rrrrrr rrrr rrrr.';
$regex = "/\\G(?:^|(?(?<!^.).)..(?:.{4})*?)\\K$y/s";
$result = preg_replace($regex, $x, $subject);
echo $result;
// => MrrMrr MrrrM rrMrrr rrrM rrMr.
ideone demo
Regex:
\G(?:^|(?(?<!^.).)..(?:.{4})*?)\Km
\G is an assertion to the end of last match (or start of string)
(?:^|(?(?<!^.).)..(?:.{4})*?) matches:
^ start of string, to check at position 1
(?(?<!^.).) is an if clause that yields:
..(?:.{4})*?) 2 chars + a multiple of 4 if it has just replaced at position 1
...(?:.{4})*?) 3 chars + a multiple of 4 for successive matches
\K resets the text matched to avoid using backreferences
I must say though, regex is an overkill for this task. This code is counterintuitive and a typical regex that proves difficult to understand/debug/maintain.
EDIT. There was a later discussion about performance vs. code readability, so I did a benchmark to compare:
RegEx with a callback (#bobblebubble's answer).
RegEx with 2 replacements in an array (#bobblebubble's suggestion in comment).
No RegEx with substr_replace (#Passerby's answer).
Pure RegEx (this answer).
Result:
Code #1(with_callback): 0.548 secs/50k loops
Code #2(regex_array): 0.158 secs/50k loops
Code #3(no_regex): 0.120 secs/50k loops
Code #4(pure_regex): 0.118 secs/50k loops
Benchmark in ideone.com
Try this
$str ="it is a test string.";
$y="r";
$x="m";
$splite_array = str_split($str);
foreach ($splite_array as $key => $val)
{
if($key % 4 == 0 && $val == $y)
{
$splite_array[$key] = $x;
}
}
$yout_new_string = implode($splite_array);
This piece of code could help you on your way:
// Define variables
$string = "it is a test string.";
$y = 'r';
$x = 'm';
// Convert string to array
$chars = explode('', $string);
// Loop through all characters
foreach ($chars as $key => $char) {
// Array keys start at 0, so we add 1
$keyCount = $key+1;
// Check if deviding the key by 4 doesn't have rest value
// This means it is devisable by 4
if ($keyCount % 4 == 0 && $value == $y) {
$chars[$key] = $x;
}
}
// Convert back to string
$string = implode($chars);
Here is one other way to do this using string access and modification by character. (Consequently, it is only useful for single-byte encoded strings.)
// First character handled outside the loop because its index doesn't match the pattern
if ($str[0] == $y) $str[0] = $x;
// access every fourth character
for ($i=3; isset($str[$i]) ; $i+=4) {
// change it if it needs to be changed
if ($str[$i] == $y) $str[$i] = $x;
}
This modifies the original string rather than creating a new string, so if that shouldn't happen, it should be used on a copy.
Late to the party, puting aside \G anchor, I'd go with (*SKIP)(*F) method:
$str = "it is a test string.";
echo preg_replace(['~\Ar~', '~.{3}\K(?>r|.(*SKIP)(?!))~'], 'm', $str);
Short and clean.
PHP live demo
I have a STRING $special which is formatted like £130.00 and is also an ex TAX(VAT) price.
I need to strip the first char so i can run some simple addition.
$str= substr($special, 1, 0); // Strip first char '£'
echo $str ; // Echo Value to check its worked
$endPrice = (0.20*$str)+$str ; // Work out VAT
I don't receive any value when i echo on the second line ? Also would i then need to convert the string to an integer in order to run the addition ?
Thanks
Matt
+++ UPDATE
Thanks for your help with this, I took your code and added some of my own, There are more than likely nicer ways to do this but it works :) I found out that if the price was below 1000 would look like £130.00 if the price was a larger value it would include a break. ie £1,400.22.
$str = str_replace('£', '', $price);
$str2 = str_replace(',', '', $str);
$vatprice = (0.2 * $str2) + $str2;
$display_vat_price = sprintf('%0.2f', $vatprice);
echo "£";
echo $display_vat_price ;
echo " (Inc VAT)";
Thanks again, Matt
You cannot use substr the way you are using it currently. This is because you are trying to remove the £ char, which is a two-byte unicode character, but substr() isn't unicode safe. You can either use $str = substr($string, 2), or, better, str_replace() like this:
$string = '£130.00';
$str = str_replace('£', '', $string);
echo (0.2 * $str) + $str; // 156
Original answer
I'll keep this version as it still can give some insight. The answer would be OK if £ wouldn't be a 2byte unicode character. Knowing this, you can still use it but you need to start the sub-string at offset 2 instead of 1.
Your usage of substr is wrong. It should be:
$str = substr($special, 1);
Check the documentation the third param would be the length of the sub-string. You passed 0, therefore you got an empty string. If you omit the third param it will return the sub-string starting from the index given in the first param until the end of the original string.
How can I add a new line characters (\n\r) in txt file every 10 characters?
What I have is a long sequence of characters, and I like to create a new line for each 10 characters.
in example, let's say I have that sequence of characters:
FadE4fh73d4F3fab5FnF4fbTKhuS591F60b55hsE
and I like to convert it to that:
FadE4fh73d
4F3fab5FnF
4fbTKhuS59
1F60b55hsE
How can I do that ?
I know that I can use a loop for that, but because the above string is an example and my string that I have to split it is really very very long, just I wander if there is any faster and more easy way to spit my string.
chunk_split($string, 10)
http://php.net/manual/en/function.chunk-split.php for more info
using chunk_split():
$str = chunk_split($str, 10, "\n\r");
or using this regex:
$str = preg_replace("/(.{10})/", "$1\n\r", $str);
And by the way did you mean \r\n (New line in Windows environment) by \n\r?
if so then the third argument for chunk_split() can be omitted.
<?php
$foo = '01234567890123456789012345678901234567890123456789012345678901234567890123456789';
$result = chunk_split ($foo, 10, "\r\n");
echo $result;
?>
As mentioned above, the use of chunk_split() might have unwanted consequences, as the break sequence is always added to the end once again.
You can instead use a combination of str_split() and implode() to first split the string every X characters and then recombine it with a break sequence. By using implode(), the break sequence will not be added to the end, again.
I've build a helper function who does this for me after 75 chars:
function createFold($s, $b = '\\n ') {
$chunks = str_split($s, 75);
return implode($b, $chunks);
}
<b><</b>?<b>php</b><br/>
$body=$row['details'];<br/>
$str = chunk_split($body, 14, "<b><</b><b>br</b><b>/</b>");<br/>
echo $str;<br/>
?