php bbcode preg match all - php

I am trying to write a function which will be checked the open bbcode tags and the close bbcode tags.
Here is what I have write so far:
public function CheckBBCodes($argText)
{
$openQuoteTagCounter = preg_match_all('[quote]', $argText, $openQuoteTagCounter);
$closeQuoteTagCounter = preg_match_all('#\[\/quote\]\s*#', $argText, $closeQuoteTagCounter);
if($openQuoteTagCounter > $closeQuoteTagCounter)
{
echo "There are more open quote tags than close quote tags!";
}
if($closeQuoteTagCounter > $openQuoteTagCounter)
{
echo "There are more close quote tags than open quote tags!";
}
}
It doesn't work. What am I forgetting?

Regex
What stands out most is your regex patterns are incorrect...
This:
$openQuoteTagCounter = preg_match_all('[quote]', $argText, $openQuoteTagCounter);
$closeQuoteTagCounter = preg_match_all('#\[\/quote\]\s*#', $argText, $closeQuoteTagCounter);
Should be:
$openQuoteTagCounter = preg_match_all('#\[quote\]#i', $argText, $openQuoteTagCounter);
$closeQuoteTagCounter = preg_match_all('#\[/quote\]#i', $argText, $closeQuoteTagCounter);
Which could be further improved:
$openQuoteTagCounter = preg_match_all('#\[quote\]#i', $argText);
$closeQuoteTagCounter = preg_match_all('#\[/quote\]#i', $argText);
The i is used to make it case insensitive in case you have tags like [QUOTE].
You don't need to escape forward slashes (/) because you're using # as a delimiter.
You don't need the third argument in the preg_match_all because you aren't doing anything with it and you're overwriting it anyway...
IF(..)
I also suggest that you use the following code structure
if(X > Y){
//Do stuff...
}
else if(Y > X){
//Do other stuff...
}
else{
//Do different stuff...
}
as opposed to if(...){...} if(...){...} if(...){...} if(...){...}

Related

PHP string comparison to a txt

The $search is a string of variables made from text inputs in a form. I am looking to see if that string is found in a txt file. I think something is wrong with my regex but I am not sure.
An existing entry to the text file would look like this Title%Author%ISBN%Publisher%Year.
My issue is that when I submit the form it goes to a blank page.
elseif ($inquiry=='search') {
$file= fopen("database.txt", "r") or die("File was not found on server");
$search = "/^[$Title."%".$Author."%".$ISBN."%".$Publisher."%".$Year]/i";
//search function
// What to look for
// open and Read from file
$lines = file('database.txt');//array
foreach($lines as $line) {
// Check if the line contains the string we're looking for, and print if it does
if(preg_match($search, $line)) {
echo $line;
} else {
echo "Search not found";
}
}
}
fclose($file);
}
You have to be aware of two things first.
The special $ char in PHP is used to denominate a variable.
When you inject a word with a preceding $ in a double quoted string, this is treated as a variable name and the variable tries to expand itself.
I'm mentioning this because of this line:
$search = "/^[$Title."%".$Author."%".$ISBN."%".$Publisher."%".$Year]/i";
So, my best guess there is that you are trying to use and expand the variable names. So, if that's the case you are ok on your intention.
But be aware you have a missmatched and no closed " after the Title.
Also remember the $ has a special meaning in regular expressions, and they are usually used to try to match the "end of the line".
Note: Your script is probably dying due to a missing " after the Title.

Why doesn't this simple PHP preg_match() function work?

Although a $_FILES array is not shown, this is intended for file upload, I have had problems with file uploading so I was not able to get the [type] part of the $_FILES array yet... but this is just a simple problem of why isn't this function working...
<?php
function getExtension() {
// global $testFile;
$extension = "./mp3/"; // also tried simply mp3 without the forwards slashes
$testFile = "song.mp3";
if(preg_match($extension, $testFile)) {
echo "match found";
}else {
echo "no match found";
}
}
getExtension();
?>
Do this:
$extension = "/mp3$/";
or
$extension = "/\.mp3$/";
ONLINE EXAMPLE
Reason being, you need the delimiters to begin and end your expression with (those are the slashes, though the can be any character) and can't have anything ahead of or behind them. The "$" will mean, find the string between the delimiters at the end of the string.
You can keep the period by escaping it (or else it will mean any character once, meaning testmp3 would be a match).
But really the best answer is as suggested in the comments - php's pathinfo() - since you are parsing a filename. Though in certain cases, you may want to do other tests for security, like check the mimetype.
If you want to keep the period, make sure you escape it.
$pattern = "/\.mp3$/";
There is a mistake in your Regular Expression :
"./mp3/" => "/\.mp3$/"
Result :
<?php
function getExtension() {
// global $testFile;
$extension = "/\.mp3$/"; // also tried simply mp3 without the forwards slashes
$testFile = "song.mp3";
if(preg_match($extension, $testFile)) {
echo "match found";
}else {
echo "no match found";
}
}
getExtension();
?>
ONLINE EXAMPLE

Conditional with htmlspecialchars

I am using this to take a special chars from the URL:
echo '' . htmlspecialchars($_GET["concert"]);
and I need to create a conditional in order to put one title and one image depending on what is on this special chars from the URL.
So something like:
if htmlspecialchars "concert" == "fanpass" do this, else do this.
Any idea how can I put a conditional statement with this?
There seems to be a confusion in the use of the words special chars. In the meaning of the PHP function htmlspecialchars, a special character is a less-than symbol (<), a greater-than symbol (>), ampersand (&) and possibly a single or double quote.
You should not apply htmlspecialchars when comparing a string with another normal string.
So, why not just:
$concert = $_GET["concert"];
if ($concert === "fanpass") {
// do one thing
} else if ($concert === "studentdiscount") {
// do another thing
} else {
// any other value
echo htmlspecialchars($concert);
// ...
}
Going by the variable names, it seems you want to use the concert parameter for something else, like a discount condition.
In that case you could start to use a new URL parameter, like for instance rate:
$concert = $_GET["concert"];
$rate = "(none)";
if (isset($_GET["discount"]) {
$rate = $_GET["discount"];
};
if ($rate === "fanpass") {
// do one thing
} else if ($rate === "studentdiscount") {
// do another thing
} else {
// any other value
// ...
}
echo "Your concert: {htmlspecialchars($concert)}<br>";
echo "Your rate: {htmlspecialchars($rate)}<br>";

PHP regex numbers in url

I've got a blog, I want to display ADS or special text on the MAIN page but not on any other page with the URI /?paged=[number]. I've tried the standard regex /^[0-9].$/ but it fails to match.
I'm not sure what I've done wrong or how to go about doing this
if (substr_count($_SERVER[REQUEST_URI], "/") > 0 AND
substr_count($_SERVER[REQUEST_URI], "/?paged=1") == 0 AND
substr_count($_SERVER[REQUEST_URI], "/?paged=2") == 0 AND
substr_count($_SERVER[REQUEST_URI], "/?paged=3") == 0 AND
substr_count($_SERVER[REQUEST_URI], "/?paged=4") == 0 AND
substr_count($_SERVER[REQUEST_URI], "/?paged=5") == 0) {
echo "display special text, banners, and other stuff";
}
This is how I'm doing it currently, but I don't want to do thousands of these...
Can you not just check for the presence of paged in the GET array?
if(!isset($_GET['paged'])) {
// You know this is the main page.
}
Try this:
if (preg_match('#paged=\d+#', $_SERVER[REQUEST_URI]) {
echo "display special text, banners, and other stuff";
}
Regex: /^[0-9].$/ would be correct for "3k" string. Analize this patterns
/page=(\d+)/
/page=([1-5])/
/^\/\?page=([1-5])$/
/page=(?<page>[1-5])/
Why not using the regexp in the GET parameter ?
<?php
$regexp = "/^(\d+)+$";
if (preg_match($regexp, $_GET['paged'])) {
#...your code
} else {
#...your code
}
Or (if you want to use the entire string) try this:
<?php
$regexp = "/^(\/\?paged)+=(\d+)+$/";

How can i have counter for php preg_match?

function getContent($xml,$tag,$id="") {
if ($id=="") {
$tag_regex = '/<'.$tag.'[^>]*>(.*?)<\/'.$tag.'>/si';
} else {
$tag_regex = '/<'.$tag.'[^>]*id=[\'"]'.$id.'[\'"]>(.*?)<\/'.$tag.'>/si';
}
preg_match($tag_regex,$xml,$matches);
return $matches[1];
}
$omg = file_get_contents("Generated/index.php");
$extract = getContent($omg,"div","lolz2");
echo $extract;
For example i have something like this. And html have something like this inside:
<div id="lolz">qwg1eqwe</div>
<div id="lolz1"><div id='lolz2'>qwdqw2cq</div>asd3qwe</div>
If we search for id lolz we get the correct answer, but if we search for lolz1 we stop at first </div> that's inner <div id="lolz2">. It's possible to keep something like counter for preg_match that's will keep how many <div>'s i pass till i find </div>?
HTML isn't a regular language, so building something like that would be overkill and is the job of an HTML parser. Please see: RegEx match open tags except XHTML self-contained tags.
The reason your code was failing however was because you were using both single and double quotes in your input but your regex didn't account for it. This works for me:
function getContent($xml,$tag,$id="") {
if ($id=="") {
$tag_regex = '/<'.$tag.'[^>]*>(.*?)<\/'.$tag.'>/si';
} else {
$tag_regex = '/<'.$tag.'[^>]*id=[\\\'"]'.$id.'[\\\'"]>(.*?)<\/'.$tag.'>/si';;
}
preg_match($tag_regex,$xml,$matches);
return $matches[1];
}
$omg = '<div id="lolz">qwg1eqwe</div>
<div id="lolz1"><div id="lolz2">qwdqw2cq</div>asd3qwe</div>';
$extract = getContent($omg,"div","lolz2");
var_dump($extract);
As long as you don't have nested elements this code will work and you won't need to use a DOM parser, though you really should for anything more complicated that might be nested (e.g. you don't have control over the input).

Categories