preg_match doesn't accept new lines - php

I know it sounds a little strange, but I'll try to explain.
use this code to check if $text contains unsupported characters:
if(!preg_match('/\A[\w .,]+\z/', $text))
{
echo "Text contains unsupported characters.";
}
Now the problem is that $text is the text entered by the user in textarea.
$text_c = $_POST['text'];
$text = mysql_real_escape_string($text_c);
echo "<form method='post'><textarea name='text'>".$text."</textarea><br /><input type='submit' name='submit' value='Submit'></form>";
Everything works perfectly, except one thing. Example, if this is text entered in textarea:
Hello, my name is John.
OK.
Hello, my name is John.
I am 20 years old.
NO. Text contains unsupported characters. (refers to the new line, because content of the textarea change and have something like: My name is John.\r\nI am 20 years old.)
My question is: what I need to change to support new lines? I hope you understand.
EDIT: I just discovered, without mysql_real_escape_string everything works exactly as I want. Is there any solution to "combine" mysql_real_escape_string with preg_match (in my case) or mysql_real_escape_string supposed to drop?

You can use \s to represent whitespace (new lines, tabs and spaces).
So your regex becomes: /\A[\w .,\s]+\z/
Note \n \r are both valid escape characters and \r\n together will match a dos line break if you don't want to include spaces/tabs.
Good reference: http://www.regular-expressions.info/reference.html

It's not the same error; rather, it's not erroring for the same reason you think it is. It's not the newlines that are tripping your regex up, it's the numbers. ;-)
Add \d to your regex as well: /\A[\w\d\s.,]+\z/

Related

PHP highlight query and escape html special characters

I'm trying to program a search function that hightlights the search query in the result. At the moment I'm using this Code $hightlight = preg_replace('/'.strtolower($query).'/', '<span class=hightlight>'.strtolower($query).'</span>', strtolower($text)); for highlighting, which works fine. The text I'm searching in is a string from a database. The problem now is if the text contains some html special characters, and is for example <test> and the user searches for <te I get the following result: <span class="hightlight"><te< span="">st></te<></span> which is interpretated as st>. This makes sense, but I don't want this. I want <test> as result with <te highlighted. So I need to escape the special characters. I know that there is the function htmlspecialchars, but how can I use it in this case? Or another function? I can't escape them before searching, because than I'm also searching in the HTML-Codes. I also can't escape them after searching, because than are the <span> Tags in the text and they will also be converted to HTML-Codes. I hope you understand my problem. Has anyone a solution for that?
Using a combination of htmlspecialchars() and a regex negative lookahead, I think we're able to solve this.
<php
$text = "this is just my really basic <test> of words";
$query = "<te";
$text = htmlspecialchars($text);
$query = htmlspecialchars($query);
$highlight = preg_replace('/'.strtolower($query).'(?![^\&]*\;)/', '<span class=highlight>'.strtolower($query).'</span>', strtolower($text));
echo $highlight;
?>
(small note, I took the liberty of changing hightlight to highlight)
DEMO
The part of this that solves the issue mentioned in your comment is the negative lookahead: (?![^\&]*\;)
That basically means anything not between & and ;.
Now, this could obviously run into issues in some edge cases where & and ; are both part of the actual text. If you're not doing any sort of text and query limitation/sanitation, I'm not sure that there's anything that will work for all possible cases.

Removing spaces from a selected mysql field using PHP

I need to select a field in mysql and put it in a hidden text field so i can select it into another file. The problem is, the name of the field has spaces in it, so it gets a little buggy. It's something like this:
$GetArea = $_GET['area'];
Then i add this into a hidden textbox:
<INPUT id=txtArea type=hidden value=".$GetArea." name=txtArea />
But it doesn't read the area when i open the site, because the area name is "Area 123" with spaces. This might be a duplicate, but searching around i really couldn't find the answer. Anyone knows of a way to remove the spaces?
To answer your direct queston of how to remove spaces from a variable: Use Regex,
$GetArea = $_GET['area'];
/// = Area 123.
$GetArea = preg_replace("/\s+/","",$_GET['area']);
/// = Area123
View a regex101 example. Regex is far better than using str_replace as in one line it can handle multiple whitespace generating characters (such as the tab character or new line breaker).
However if [in another situation] you want to preserve the spaces and record them you can substitute them for something else such as a _ character:
$GetArea = $_GET['area'];
/// = Area 123.
$GetArea = preg_replace("/\s+/","_",$_GET['area']);
/// = Area_123
The above example means that when you send the data back to the database you can do a preg_replace search and replacement for all _ characters substituted into replace the space character, as needed. (although MySQL only accepts spaces in Column names when properly encased in backticks).
BUT
I would also strongly suggest you get into a habit of encasing your HTML into quotes (single usually) rather than just hanging them out as they are, as this is the principle cause of your issue. so to quote your HTML:
print "<INPUT id='txtArea' type='hidden' value='".$GetArea."' name='txtArea' />";
/** I made an assumption from your syntax your HTML was being printed by PHP **/
This means that you can keep your spaces in your data value of the HTML input element because the whole value section is defined and clearly wrapped in single quote marks.
On a broader note, you really should be looking at not using $_GET and instead transfering data page-to-page with $_POST. Also please research SQL injection and how to prevent it as well as Cross Site Scripting and how to mitigate that. Spaces in MySQL column names is a good habit to avoid.
You should probably use something like this :
$str= str_replace(' ', '', $str);

Newline Conversion in Submitted Text in PHP

I have a system set up for users to submit their articles into my database. Since it will just be HTML, I don't want to expect them to know to type <br /> every time there's a newline, so I am using the PHP function nl2br() on the input.
I'm also providing an article modification tool, which will bring their articles back into the form (this is a different page, however) and allow them to edit it. In doing this, the <br /> elements were appearing also (with newlines still). To remedy the elements appearing (which I had expected, anyway) I added preg_replace('/<br(\s+)?\/?>/i', "\n", mysql_result($result,$i,"content")) which I had found in another question on this site. It does the job of removing the <br /> elements, but since it is replacing them with newlines, and the newlines would have remained originally anyway, every time the post is edited, more and more newlines will be added, spacing out the paragraphs more and more each time. This is something a user won't understand.
As an example, say I enter the following into the article submission form:
Hello, this is my article.
I am demonstrating a new line here.
This will convert to:
Hello, this is my article.<br />
I am demonstrating a new line here.
Notice that, even though the newline character was converted, there is still a newline in the text. In the editing form, the <br /> will be converted back to newline and look like this:
Hello, this is my article.
I am demonstrating a new line here.
Because the <br /> was converted to a newline, but there was already a newline. So I guess what I'm expecting is for it to originally be converted to something like this:
Hello, this is my article.<br />I am demonstrating a new line here.
I'm wondering ... is there a way to stop the nl2br() function from maintaining the original newlines? Might it have to do with the Windows \r\n character?
The function you're using, nl2br is used for inserting them, but not replacing them. If you want to replace \n with <br /> you just need to use str_replace. Like so:
$string = str_replace("\n","<br />",$string);
There is absolutely no need for regex in this situation.
It seems like the problem you described is not a bug, but a feature of bl2br. You could just write your own function for it, like:
<?php
function NlToBr($inString)
{
return preg_replace("%\n%", "<br>", $inString);
}
?>
I found this one in the comments of the documentation of the nl2br-function in the PHP Manual: http://php.net/manual/de/function.nl2br.php. If the one I posted did not work for you, there should be plenty more where it came from.
(Or just use the function from the other Answer that was just posted, I guess that should work, too)
This should fix it:
preg_replace('/<br(\s+)?\/?>(?!\s*\n)/i', "\n", mysql_result($result,$i,"content"))
You cannot simply remove the breaks, because they might be on the same line. This regex will replace all breaks with newline but not those that are followed by the newline.
It will leave the <br>\n in the text. Additional regex will get rid of them:
preg_replace('/<br(\s+)?\/?>/i', "", $res)

Removing Break Lines

I've asked this question before but I didn't seem to get the right answer. I've got a problem with new lines in text. Javascript and jQuery don't like things like this:
alert('text
text);
When I pull information from a database table that has a break line in it, JS and jQuery can't parse it correctly. I've been told to use n2lbr(), but that doesn't work when someone uses 'shift+enter' or 'enter' when typing text into a message (which is where I get this problem). I still end up with separate lines when using it. It seems to correctly apply the BR tag after the line break, but it still leaves the break there.
Can anyone provide some help here? I get the message data with jQuery and send it off to PHP file to storage, so I'd like to fix the problem there.
This wouldn't be a problem normally, but I want to pull all of a users messages when they first load up their inbox and then display it to them via jQuery when they select a certain message.
You could use a regexp to replace newlines with spaces:
alert('<?php preg_replace("/[\n\r\f]+/m","<br />", $text); ?>');
The m modifier will match across newlines, which in this case I think is important.
edit: sorry, didn't realise you actually wanted <br /> elements, not spaces. updated answer accordingly.
edit2: like #LainIwakura, I made a mistake in my regexp, partly due to the previous edit. my new regexp only replaces CR/NL/LF characters, not any whitespace character (\s). note there are a bunch of unicode linebreak characters that i haven't acknowledged... if you need to deal with these, you might want to read up on the regexp syntax for unicode
Edit: Okay after much tripping over myself I believe you want this:
$str = preg_replace('/\n+/', '<br />', $str);
And with that I'm going to bed...too late to be answering questions.
I usually use json_encode() to format string for use in JavaScript, as it does everything that's necessary for making JS-valid value.

How can I get a new line in a textarea?

I have a textarea that I need to put a new line into with some dashes above. I have tried nl2br but that just echos the <br> tag. I have also tried to concat the \n but it is ignored.
What this is for is an email like system. When the user replies to an email, I want the old message below with a seperator like a few dashes. I can't get this to work though.
new message starts here
--------------
old message here
Can someone please give a hand?
Thanks.
Try a return character: \r
According to this article, the \n newline character should work. What is happening when you are inserting the \n character into the string using double quotes?
This works for me:
<textarea>test
testing</textarea>
it properly creates the next line. Check to make sure your source code looks something like that, with n actual line break in the source where you want it to be.

Categories