PHP replace last x character in console - php

I want to replace last x character from console output.
I can remove complete line by using \r.
But is there a way to just remove last x character from console output ?

In PHP:
To print a backspace character, use 0x08. BUT, there's a problem. If you follow that by a newline "\n" (which you normally would) then the cursor is moved back to EOL, and the characters are exposed again. Good news is that if you follow the 0x08 with the same number of spaces, it works fine. For example, to remove the last two characters:
<?php
print "Hello";
printf("%c%c",0x08,0x08);
print " \n";
?>
Which prints Hel. Note the use of printf() with %c to use an integer (0x08) as a character.
For a generic way to remove x number of characters:
<?php
$x = 4;
$str = "Those who are about to die salute you";
$hacky = str_repeat(chr(0x08),$x).str_repeat(" ",$x);
print "$str$hacky\n";
?>
which prints Those who are about to die salute. Note the use of chr(0x08) here, which returns the character at position 8 in the character set.

You could use the cut command.

Related

json_encode() character 127 ASCII

Consider the following code:
$str = '';
for ($i=0x0; $i<=0x7f; $i++) {
$str .= chr($i);
}
echo json_encode($str);
The result is:
"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-.\/0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
There are all but one ASCII characters (the last one): 127 (0x7f).
Is there a way to show that character? (for instance: "\u007f")
Delete (DEL) is a control character in the ASCII character set with the coding 0x7f or 127 decimal. This character is saved as ASCII in the JSON string. This character can be made visible by outputting the JSON string in hexadecimal format.
$jsonStr = json_encode(chr(0x7f));
echo bin2hex($jsonStr); //227f22
22 is the encoding for a double quotation mark ("). echo is not suitable for checking what is in a string. There are always misunderstandings. Control characters (including DEL) are only displayed as spaces in the browser. If you look closely at the result of your code example, you will see the space at the end.
I am not sure, but I think this is what you are searching for:
U+007F
Also see this answer: Why no symbols defined for ascii values from 127 to 159

How to get a character with diacritical mark from a string in php?

I'm writing a code that accepts the middle name of a person, convert it to upper then get its first character.
Example the user input the name "winston", then I'll get a capitalise "W".
I can use either of the 2 codes to get the first character of string and it works fine.
mb_strtoupper(substr($name,0,1));
or
mb_strtoupper($name[0]);
I'm using mb_strtoupper() so that it can convert a character with diacritics like ñ.
My problem is when the names first character have a diacritical mark.
Ñana
I'm testing a code,
$name_1 = 'Ñana';
echo strtoupper(substr($name_1,0,1));
echo '<br>';
echo strtoupper($name_1[0]);
The result
I tried to increase index of $name_1 and the parameter of substr().
$name_1 = 'Ñana';
echo strtoupper(substr($name_1,0,2));
echo '<br>';
echo strtoupper($name_1[1]);
The result
My code works if the the first character of the string don't have diacritics.
How should I handle it? Or How can I handle this kind of situation?
You cannot use substr for UTF-8 encoded string, because you cut 1 byte out of a single multibyte character. Use mb_substr instead from the Multibyte String Functions:
echo mb_strtoupper(mb_substr($name_1, 0, 1));

PHP - While writing a fixed length file, PHP is not processing `\t` as Tab after the first one. Why?

I am writing a fixed length file using PHP. Each character will have a predefined length. If characters are less than the length then it will insert that number of blank spaces. Each field is separated by TAB.
$str1 = str_pad('ten',10)."\t";
$str2 = str_pad('seven',7)."\t";
$str3 = str_pad('fifteen',15)."\t";
$str = $str1.$str2.$str3;
file_put_contents("newfile.txt",$str);
But TAB is not working as expected.
I can see TAB only after first word (ten). After that there are no more TABs in the output file.
Your text is rendered correctly.
A tab does not mean a fixed number of spaces or a printable character. It means "forward the cursor to the next tab stop".
A tab stop in computers is typically set to every 4 or 8 characters. It's a display issue that will behave differently across various systems and user configurations.
If you copy your output to your preferred text editor and manually select it, you can see spaces as dots and tabs as lines, as in the examples below:
Note: your output is the first line ("ten seven fifteen"). I added the second and third lines to illustrate the configured tab length in the text editor.
If we set tab length to 4:
The first string contains 10 chars ("t", "e", "n" plus 7 dots), and the next tab stop is at the 12th char. So it's only 2 chars away, that's why your tab character (grey line) is only 2 chars long. The second string has 7 chars, and the next stop is only 1 char away so the tab will have only 1 char. It's the same logic for the third string.
If we set tab length to 8:
It follows the same logic, but in this example, the first tab is now bigger because the nearest stop is at position 16, so the tab has 6 chars. The second and third tabs have coincidentally only one char.
If we set tab length to an odd number like 3:
This is not common, but it's something possible. In this example, we can see all tabs as multiple spaces. It follows the same logic as explained above, but we can visually see that your code is producing the expected output.
Notice that I did not change your output in any way. I just played with the editor's configuration.
If you want a fixed length spacer between your chars, you should use "\s" instead. You can repeat the character like this: "\s\s\s\s", or using str_repeat("\s", 4); or "\s" * 4 if you were using Python.
It looks like when you are adding the padding to the string it is considering the TAB character as a space. I would suggest you change the code to the following to get the desired effect.
$str1 = str_pad('ten',10);
$str2 = str_pad('seven',7);
$str3 = str_pad('fifteen',15);
$str = $str1."\t".$str2."\t".$str3."\t";
file_put_contents("newfile.txt",$str);
If there are a huge number of strings I would suggest putting them in an array and doing a foreach loop appending the tab character at the end.
By the way there is no tab character in your final string all you are seeing is the padding of spaces after the strings
In Your Case, try this code :
$str1 = str_pad('ten',10)."\t";
$str2 = str_pad('seven',7)."\t\t";
$str3 = str_pad('fifteen',15)."\t\t";
$str = $str1.$str2.$str3;
file_put_contents("newfile.txt",$str);

PHP - strspn($input, $allowed_chars) can not seem to be able to work with "\r\n"

i have a textarea box
<textarea>abc
d</textarea>
i post this to the php script.
in php script i have..:
$a = $_POST["a"];
$allowed_chars= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .<>="';
$scan = strspn($a, $allowed_chars);
if ($scan < strlen($a)){
echo "not allowed char after the $scan : ". substr($a, $scan,1)
}
this will print this on the web browser:
not allowed char after the 3 :
obviously the new line is a problem.
i want to know what i can add to my
$allowed_chars
list. i tried adding
\\
( escaped forward? backward? slash )
it did not work.
after the
not allowed char after the 3 :
it is suppose to tell me the character causing the problem but it is simply empty.. showing nothing. how can it be designed so it can show the conflicting character ?
UPDATE
this does not work
$a = $_POST["a"];
$allowed_chars= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .<>="\r\n';
$scan = strspn($a, $allowed_chars);
if ($scan < strlen($a)){
echo "not allowed char after the $scan : ". substr($a, $scan,1)
}
( added \r\n to the list )
update 2
this also does not work:
$allowed_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "\r\n"';
update 3
solution seems to be to first use php's nl2br() function on the "$input".
in that post
Escape Regex Newline
you can see that to make a new line char is : '\n'
so for regexp could be '\n'
and then you can add as \ as you tell before
expect help you
The problem with your script is that new line are multiple characters that define a distinct character. While you state \r\n that means you're on Windows and this code will also not work on a Linux server.
I'm not sure what you're trying to do but from the code I see its better to use Regex.
$s = 'some string I want to see the data on.';
$var = preg_match ( '/[A-z0-9].*/' , $s , $m);
print_r($m);
In this case it will only fetch the data before a line break which is also compatible with Linux.
This, unless you use the multi-line modifier in regex. Then you can check if the count($m) is greater then 1 it means it has multiple matches.
The regex [A-z0-9].* means match in range of A-Z & a-z & 0-9. Cause regex runs on a lower level then PHP (on the CPU) it is much more efficient at this task.
Regex is like a search code for a string, its extremely flexible and I would suggest you dive into the subject.

Matches lasts non-words with last word on string

I need matches the lasts non-words with last word on string (both optionals). The matches will be removed from original string by replacing it by null. My current results are:
Regular expression:
\W* # Matches optional lasts non-words.
\w* # Matches optional last word.
$
Working cases: unit tests here
String Removed Result
----------------------------------------------------------------------------
"Hello World!" "!" "Hello World"
"Hello World" " World" "Hello"
"Hello " " " "Hello"
"Hello" "Hello" ""
"Hello; World!" "!" "Hello; World"
"Hello; World" "; World" "Hello"
"Hello;" ";" "Hello"
Of course, I'm having a problem. I want accept HTML entities as part of the word, but as it have non-words characters (the ending semicolon), it final semicolon is matched and replaced incorrectly.
Currently I expects only that is matches simple HTML entities, basically it &\w+; (like &aaccute;), I'll improve it later (for now, let uses it to simplify answer).
What I expect: unit tests here, failing for now
String Removed Result
----------------------------------------------------------------------------
"Hell&aaccute; World!" "!" "Hell&aaccute; World"
"Hell&aaccute; World" " World" "Hell&aaccute;"
"Hell&aaccute;" "Hell&aaccute;" ""
"&aaccute; &aaccute;" " &aaccute;" "&aaccute;"
"&aaccute; " " " "&aaccute;"
"&aaccute;" "&aaccute;" ""
I just need add the HTML entities expression in some place to avoid matches it on first expression (\W*), I guess. But I tried somethings and it does not worked.
I don't know of a way to accomplish your regex match goal as specifically stated. I believe that you'd need a variable width negative lookback to avoid matching unwanted HTML entities, and that doesn't exist in any implementation that I've seen.
But, if your true goal is just to split the strings in the manner you've specified, there are two ways to accomplish that goal.
#1
You can match and consume the preliminary characters as a group, replacing the original string with just the first group match (${result}). ${removed} will have the text matching the removed characters as you described in your question.
^(?<result>.*?(?:(?:&[a-z]+;)|\w)*?)(?<removed>(\W*)((?:&[a-z]+;|\w)*))(?<=.)$ # regex101
Since all matches are optional, the trailing (?<=.) is present to avoid a matching completely empty lines. I'm also using a simplified definition of HTML entities as you suggested (eg, assuming lowercase and ignoring numeric entities such as "<").
All updated unit tests pass.
#2
Alternatively, you can reverse the strings and use something like this regex to match the desired characters to remove:
^(?<removed>((?:;[a-z]+&|\w)*)((?:[^\w;]|;(?![a-z]+&))*))(?<=.)
Then, after removing the characters, re-reverse the string. ${removed} will have the characters that were removed (as a reversed string). Note that, as of yet, I've only done some preliminary testing on the "reversed" regex.
You cannot use \w because it does not include HTML entities as you point out.
Instead, accept any combination of letters and HTML entities, something like this:
([a-zA-Z]*(&[a-zA-Z]+;)*[a-zA-Z]*)+\s([a-zA-Z]*(&[a-zA-Z]+;)*[a-zA-Z]*)+$
https://regex101.com/r/pH7tK2/2

Categories