How to remove formatting characters? - php

I set formatting mask on a textfield :
$(document).ready(function() {
$("#budget_para_prevision").inputmask("9999999999999.99"); // 13 digits before "."
});
The problem happens after posting the form when the length of the digits before the "." sign is less than 13 then the formatting characters are written automatically with the $_POST variable , it gives something like this :
391000000000_.__
So how to remove the _ and the . sign in this case ?

You can remove the unwanted characters using a combination of str_replace and rtrim. Something like this:
$input = "391000000000_.__";
$result = str_replace("_", "", $input); // Remove instances of underscore.
$result = rtrim($result, "."); // Remove the dot if it's the last character.
Or you can just do the whole lot with a single rtrim:
$result = rtrim($input, "._");

You can have part of your mask be optional. Anything listed after '?'
within the mask is considered optional user input. The common example
for this is phone number + optional extension.
$(document).ready(function() {
//if 12 and more digits are optional
$("#budget_para_prevision").inputmask("999999999999?9.99");
});
From docs

I guess it would depend on what jQuery inputmask plugin you are using exactly, but if it is Robin Herbots plugin, you can make parts of your input optional and specify lengths:
$(document).ready(function() {
$("#budget_para_prevision").inputmask("9{1,13}[.99]"); // 13 digits before "."
});
Of course you could also fix it at the backend with rtrim($input, "._") but preventing the input in the first place would be better.

Related

PHP Check if Many spaces before or after a string

On my website, after a user registers they can change their username at any time. The minimum amount of characters is 6 and max amount is 25.
Here's some of the coding to check the length and remove characters:
$users_new_name = strip_tags($_POST['new_name']);
$new_name = preg_replace("/[^0-9a-zA-Z -]/", "", $users_new_name);
// Check Length
if (ctype_space($new_name)) {
$message = die('<span class="Fail">Error: Name Must Be At least 6 Characters Long!</i></span>');
}
if(strlen($new_name) < 6) {
$message = die('<span class="Fail">Error: Name Must Be At least 6 Characters Long!</i></span>');
}
if(strlen($new_name) > 25) {
$message = die('<span class="Fail">Error: Name Can\'t Be More Than 25 Characters Long!</i></span>');
}
The issue I'm having is if you type in 5 spaces and then a letter or number, There new name will be that letter or number; Or if you type in a letter or number then 5 spaces. How could I prevent this from happening?
Here's a screenshot of the example
I do not understand why tags would be in a POST.
Spaces becomes a non-issue if you change:
$users_new_name = strip_tags($_POST['new_name']);
To
$users_new_name = trim(strip_tags($_POST['new_name']));
Or ideally (strip tags is unnecessary):
$users_new_name = trim($_POST['new_name']);
Change the RegEx expression to /[^0-9a-zA-Z]/ to eliminate spaces and dashes.
It sounds like you need trim() to trim any spaces from the username. See http://php.net/trim
ltrim() will trim any leading spaces. rtrim() will trim any spaces at the end of the string.
This is fairly simple and it's something I've had to deal with on systems before.
If you make the first thing you call, this preg_replace, the rest of you code should catch it;
$name = preg_replace('~[\s]+~', '', $name);
This simply checks if there is a space, or more than one, then replaces with a single space.
So " l" would return " l" - failing your 5 character minimum.
Use trim() around this and you should have it working to something acceptable (Depending on your definition of acceptable - worked in my use-case)

Erasing C comments with preg_replace

I need to erase all comments in $string which contains data from some C file.
The thing I need to replace looks like this:
something before that shouldnt be replaced
/*
* some text in between with / or * on many lines
*/
something after that shouldnt be replaced
and the result should look like this:
something before that shouldnt be replaced
something after that shouldnt be replaced
I have tried many regular expressions but neither work the way I need.
Here are some latest ones:
$string = preg_replace("/\/\*(.*?)\*\//u", "", $string);
and
$string = preg_replace("/\/\*[^\*\/]*\*\//u", "", $string);
Note: the text is in UTF-8, the string can contain multibyte characters.
You would also want to add the s modifier to tell the regex that .* should include newlines. I always think of s to mean "treat the input text as a single line"
So something like this should work:
$string = preg_replace("/\\/\\*(.*?)\\*\\//us", "", $string);
Example: http://codepad.viper-7.com/XVo9Tp
Edit: Added extra escape slashes to the regex as Brandin suggested because he is right.
I don't think regexp fit good here. What about wrote a very small parse to remove this? I don't do PHP coding for a long time. So, I will try to just give you the idea (simple alogorithm) I haven't tested this, it's just to you get the idea, as I said:
buf = new String() // hold the source code without comments
pos = 0
while(string[pos] != EOF) {
if(string[pos] == '/') {
pos++;
while(string[pos] != EOF)
{
if(string[pos] == '*' && string[pos + 1] == '/') {
pos++;
break;
}
pos++;
}
}
buf[buf_index++] = string[pos++];
}
where:
string is the C source code
buf a dynamic allocated string which expands as needed
It is very hard to do this perfectly without ending up writing a full C parser.
Consider the following, for example:
// Not using /*-style comment here.
// This line has an odd number of " characters.
while (1) {
printf("Wheee!
(*\/*)
\\// - I'm an ant!
");
/* This is a multiline comment with a // in, and
// an odd number of " characters. */
}
So, from the above, we can see that our problems include:
multiline quote sequences should be ignored within doublequotes. Unless those doublequotes are part of a comment.
single-line comment sequences can be contained in double-quoted strings, and in multiline strings.
Here's one possibility to address some of those issues, but far from perfect.
// Remove "-strings, //-comments and /*block-comments*/, then restore "-strings.
// Based on regex by mauke of Efnet's #regex.
$file = preg_replace('{("[^"]*")|//[^\n]*|(/\*.*?\*/)}s', '\1', $file);
try this:
$string = preg_replace("#\/\*\n?(.*)\*\/\n?#ms", "", $string);
Use # as regexp boundaries; change that u modifier with the right ones: m (PCRE_MULTILINE) and s (PCRE_DOTALL).
Reference: http://php.net/manual/en/reference.pcre.pattern.modifiers.php
It is important to note that my regexp does not find more than one "comment block"... Use of "dot match all" is generally not a good idea.

Is there a way by default to require ALL words in full text searching?

I'm trying to find a way to make it so when users do a search that by default ALL words are required.
This seemed easy enough at the beginning, just break the words up and add a + sign to the start of each word; however when you start to try and implement the other operators it get's complicated.
This is what I have so far..
function prepareKeywords($str) {
// Remove any + signs since we add them ourselves
// Also remove any operators we don't allow
// We don't allow some operators as they would have no use in the search since we don't order our results by relevance
$str = str_replace(array('+','~','<','>'), '', $str);
// Remove anything more than once space
$str = preg_replace('/\s{2,}/', ' ', $str);
// Now break up words into parts
$str = str_getcsv($str, ' ', '"');
// Now prepend a + sign to the front of each word
foreach ($ks as $key => $word) {
// First we check to make sure the start of the word doesn't already contain an operator before we add the + sign to the start
if (in_array($word{0}, array('-','<','>','~'))) {
} else {
$ks[$key] = '+' . $word;
}
}
// Now put word back to string
//$ks = implode(' ', $ks);
}
As you can see it only gets so far at the moment, respects quoted strings, but then I start thinking about not breaking up () as well, and then what if that contains nested double quotes or vice versa.... it starts getting very hairy.
So I'm trying to figure out if there is a way that I can do what I want without messing with the string and just making all words required by default UNLESS the user specifically negates them with a -.
Surely you can make use of preg_match() and \b in the pattern as the word boundary?
You search terms can then be split with something like
preg_match_all('/\b(.*)\b/', $matches);
I might be on the wrong thinking as it's late here, but it might give you something to go on

php preg match a-zA-Z and only one space between 2 or more words

For my PHP script I have this code:
if (!preg_match("/[^A-Za-z]/", $usersurname))
$usersurname_valid = 1;
This worked untill I realized a surname can be two or more words... doh.
Anyone can tell me how to write this code if I want to allow 1 space between two worlds? For example:
Jan Klaas is now wrong and Jan Klaas should be allowed, also Jan Klaas Martijn and so on should be allowed.
Even better would be a preg replace, to replace two or more spaces with 1, so when you write: Jan(space)(space)Klaas or Jan(space)(space)(space)(space)Klaas, it would return Jan(space)Klaas.
I searched around for a while but somehow I just can't get this space matching to work..
PS: When I got this working, I will apply this for the mid and last name too ofcourse.
===========================================
EDIT: After you helping me out, I re-wrote my code to:
// validate usersurname
$usersurname = preg_replace("/\s{2,}/"," ", $usersurname);
if (!preg_match("/^[A-Za-z]+(\s[A-Za-z]+)*$/",$usersurname))
$usersurname_valid = 1;
// validate usermidname
$usermidname = preg_replace("/\s{2,}/"," ", $usermidname);
if (!preg_match("/^[A-Za-z]+(\s[A-Za-z]+)*$/",$usermidname))
$usermidname_valid = 1;
// validate userforename
$userforename = preg_replace("/\s{2,}/"," ", $userforename);
if (!preg_match("/^[A-Za-z]+(\s[A-Za-z]+)*$/",$userforename))
$userforename_valid = 1;
and the error notifications
elseif ($usersurname_valid !=1)
echo ("<p id='notification'>Only alphabetic character are allowed for the last name. $usersurname $usermidname $userforename</p>");
// usermidname character validation
elseif ($usermidname_valid !=1)
echo ("<p id='notification'>Only alphabetic character are allowed for the middle name. $usersurname $usermidname $userforename</p>");
// userforename character validation
elseif ($userforename_valid !=1)
echo ("<p id='notification'>Only alphabetic character are allowed for the (EDIT) first name. $usersurname $usermidname $userforename</p>");
Replacing the spaces are working well and I need this preg_match to check on on A-Za-z + space. I think in this case it doesn't matter if it's matching more than 1 spaces because it's replaced anyway, right?
EDIT:
Solution for my case:
$usersurname = preg_replace("/\s{2,}/"," ", $usersurname);
if (!preg_match("/[^A-Za-z ]/", $usersurname))
This does the work. Thanks for helping out, J0HN
Well, solving the problem you have in mind:
if (!preg_match("/^[A-Za-z]+(\s[A-Za-z]+)*$/",$usersurname)) { ... }
But, well, it's just a part of the solution, and it's not bulletproof. Look at the list of common mistakes when handling names.
So, you'd better to re-think on your validation approach.
Replacing the multiple spaces is simpler to achieve as a separate instruction, something like
$processed_usersurname = preg_replace("/\s{2,}/"," ", $usersurname);
This will match and replace any two or more consequent whitespace characters (space, tab, linebreak and carriage return) to single space

Regex - Strip non numeric and remove cents if any

I'm currently working on a project in PHP and I'm in need of some Regex help. I'd like to be able to take a user inputted monetary value and strip all non numeric and decimal places/cents.
Ex:
'2.000,00' to '2000'
'$ 2.000,00' to '2000'
'2abc000' to '2000'
'2.000' to 2000
(I'm using non US currency formatting)
How can I do this? I'd appreciate the help - Thanks
You can do:
$str = preg_replace('/[^0-9,]|,[0-9]*$/','',$str);
$output = preg_replace('/[^0-9]/s', '', $input);
that should replace non numeric chars with empty strings.
This should do what you want.
$your_string_without_letters = preg_replace('\w+', '', $your_string)
preg_match('[0-9][0-9.]*', $your_string_without_letters, $matches);
$clean_string = $matches[0];
The match will start as soon as the first number is found, and stop when it hits something that is neither a number nor a dot (ie. a comma or the end of the string in your examples)
EDIT : forgot to remove the letters inside the value first.
(Just a personal opinion, but if a user writes chracters that are not numbers, dots, commas or currency symbols I would refuse the input instead of trying to clean it)
On the client side I use classes on the inputs:
$("input.intgr").keyup(function (e) { // Filter non-digits from input value.
if (/\D/g.test($(this).val())) $(this).val($(this).val().replace(/\D/g, ''));
});
$("input.nmbr").keyup(function (e) { // Filter non-numeric from input value.
var tVal=$(this).val();
if (tVal!="" && isNaN(tVal)){
tVal=(tVal.substr(0,1).replace(/[^0-9\.\-]/, '')+tVal.substr(1).replace(/[^0-9\.]/, ''));
var raVal=tVal.split(".")
if(raVal.length>2)
tVal=raVal[0]+"."+raVal.slice(1).join("");
$(this).val(tVal);
}
});
$("input.money").keyup(function(){ money($(this)) })
.blur(function(){ money($(this),1); });
//----------- free-standing functions --------------
function money($inElem,inBlur,inDec){//enforces decimal - only digits and one decimal point. inBlur bool for final slicing to sets of 3 digits comma delimted
var isBlur=inBlur||0;//expects boolean (true/false/0/1 all work), default to 0 (false)
var dec=inDec || 2;
if(/[^,.0-9]/g.test($inElem.val()))//if illegal chars, remove and update
$inElem.val($inElem.val().replace(/[^,.0-9]/g, ""));
var ra=$inElem.val().split(".");
if(ra.length>2 || ra.length>1 && ra[ra.length-1].length>2){//if too more than 1 "." or last segment more than dec digit count, fix and update
if(ra[ra.length-1].length>2) ra[ra.length-1]=ra[ra.length-1].substr(0,dec);//shorten last element to only dec digit count
$inElem.val(ra.slice(0,ra.length-1).join("")+"."+ra[ra.length-1]);//glom all but last elem as single, concat dec pt and last elem
}
if(inBlur){
ra=$inElem.val().split(".");
var rvsStr=zReverse(ra[0].replace(/,/g,""));
var comDelim="";
while(rvsStr.length>0){
comDelim+=rvsStr.substr(0,3)+",";
rvsStr=rvsStr.substr(3);
}
$inElem.val(zReverse(comDelim).substr(1)+(ra.length==2?"."+ra[1]:""));
}
}
function zReverse(inV){//only simple ASCII - breaks "foo 𝌆 bar mañana"
return inV.split("").reverse().join("");
}

Categories