Coldfusion Regex question - regex

I currently have a coldfusion regex that checks whether a string is alphanumeric or not.
I would like to open that up a bit more to allow period and underscore characters. How would I modify this to allow that?
<cfset isValid= true/>
<cfif REFind("[^[:alnum:]]", arguments.stringToCheck, 1) GT 0>
<cfset isValid= false />
</cfif>
Thanks

No need for cfif - here's a nice concise way of doing it:
<cfset isValidString = NOT refind( '[^\w.]' , Arguments.StringToCheck )/>
Alternatively, you can do it this way:
<cfset isValidString = refind( '^[\w.]*$' , Arguments.StringToCheck ) />
(To prevent empty string, change * to +)
This method can make it easier to apply other constraints (e.g. must start with a letter, etc), and is a slightly more straight-forward way of expressing the original check anyway.
Note that the ^ here is an anchor meaning "start of line/string" (with $ being the corresponding end), more information here.

This should do it.
<cfset isValidString= true/>
<cfif REFind("[^[:alnum:]_\.]", arguments.stringToCheck, 1) GT 0>
<cfset isValidString= false />
</cfif>
Also using "isValid" for a variable name is not a great practice. It is the name of a function in ColdFusion and could cause you issues someday.

Would this work for you?
refind("[\w\d._]","1234abcd._")

Related

Using ColdFusion, how do I replicate a compare statement with listFind?

I'm setting up something to allow me to masquerade as another user in my system. But, I want to use listFind instead of a compare() method.
<cfif compare(session.userName, "userOne") EQ 0>
<cfset #session.userName# = "userThree">
</cfif>
In the above statement, I'm trying to conform it to a listFind, where if userOne is currently logged in, then set the session.userName to userThree. But, I'm having trouble.
What I have thus far...
<cfif #ListFind("userOne, UserTwo")#>
<cfset #session.userName# = "userThree">
</cfif>
You will need to provide two independent arguments to ListFind. At the moment you are providing one string. The list is also the first arguments and string search for is the second.
<cfif ListFind("userOne", session.userName)>
<cfset session.userName = "userThree">
</cfif>
On a side note, the hashes are only necessary for string interpolation. In other words, only when you want a variable/expression to be evaluated and inserted into a string.

ColdFusion checking empty form fields

I am very new to ColdFusion and was curious if someone could tell me how to check to see if a form field is empty or not.
For example let's say we set it up like this:
<cfinput
type="text"
name="firstName"
id="firstName"
value="#form.firstName#"
>
How do I call this later to use it in another form? I tried many things but I am missing something somewhere.
<cfif (form.firstName) EQ 0>
You can check if the length of the field is 0, using trim would remove any leading or trailing spaces.
<cfif len(trim(form.firstName)) EQ 0>
I have always use a two fold check. IsDefined evaluates a string value to determine whether the variable named in it exists.
<CFIF NOT IsDefined("FORM.firstname") OR
FORM.firstname EQ "">
Reference: http://help.adobe.com/livedocs/coldfusion/8/htmldocs/help.html?content=functions_in-k_14.html
The most straightforward way is:
<cfif form.firstName IS "">
It simply checks to see if the specified form field is an empty string ("").
Another way of writing the same thing would be:
<cfif len(form.firstName) EQ 0>
This checks to see if the length of the form field value is 0 (empty string).
This second method can be shortened a little bit?
<cfif len(form.firstName)>
Assume that form.firstName is empty. This would then become . In boolean evaluation, 0 is false. Assuming the value was not empty, it would become . A non-zero number evaluates to true.
Some developers prefer checking for emptiness by checking comparing against an empty string. See len(x) better or x NEQ "" better in CFML?
<cfif trim(form.firstName) NEQ "">
<cfscript> is also an option
<cfscript>
if (trim(form.firstName) != "") {
...
Yoda conditions work too
<cfscript>
if ( "" != trim(form.firstName)) {

ColdFusion isDefined

I am trying to check to see if data exist in my form If data does not exist I want to assign it to O. How can I do this.
<cfif not isDefined("FORM.Age")>
cfset FORM.Age = "0"
<cfif>
Generally the best practice is considered to be to avoid isDefined. This is because isDefined will search all scopes until it finds a matching variable. So it's more efficient to use structKeyExists, eg:
<cfif NOT structKeyExists(form, "age")>
<cfset form.age = 0>
</cfif>
Also, another way to achieve this is to use cfparam, and specify 0 as the default:
<cfparam name="form.age" default="0">
You're almost there:
<cfif not isDefined("FORM.Age")>
<cfset Form.Age = 0>
</cfif>
Technically what you have is fine once you enclose the cfset in tags < and >. Assuming that omission is just a typo, could it be you are trying to use it with a text field?
Text fields always exist on submission. The value may be an empty string, but the field itself still exists, so IsDefined will always return true. If that is the case, you need to examine the field length or value instead. Then do something if it is empty according to your criteria. For example:
<!--- value is an empty string --->
<cfif NOT len(FORM.age)>
do something
</cfif>
... OR
<!--- value is an empty string or white space only --->
<cfif NOT len(trim(FORM.age))>
do something
</cfif>
... OR
<!--- convert non-numeric values to zero (0) --->
<cfset FORM.Age = val(FORM.Age)>
There are actually two things you want to to ensure. First, make sure this page was arrived at by submitting the proper form. Next, ensure you have a numeric value for the form.age variable. Here is an example of how you might want to code this:
<cfif StructKeyExists(form, "age") and cgi.http_referrer is what it should be>
<cfif IsNumeric(form.age) and form.age gt 0>
<cfset AgeSubmitted = int(form.age)>
<cfelse>
<cfset AgeSubmitted = 0>
</cfif>
...more code to process form
<cfelse>
...code for when page was not arrived at properly
</cfif>

advanced cfif statement

How would I create this statement in CF?
<cfif (not isdefined("URL.room") or #URL.room# EQ "")
and (not isdefined("URL.system" or #URL.system# EQ "")
and (not isdefined("URL.date") or #URL.date# EQ "")>
Obviously the parentheses don't work, but illustrate what I am trying to accomplish. What is the syntax for this?
EDIT:
Ok, I understand how to use EQ and all that. I posted this in a bit of a hurry. My question is about the parentheses. Is it syntactically correct to use them this way?
EDIT: Ok, I understand how to use EQ
and all that. I posted this in a bit
of a hurry. My question is about the
parentheses. Is it syntactically
correct to use them this way?
Syntactically, yes. The code's syntax is correct and will not throw syntax errors.
However, it's not necessarily the best way to do it. At the very least you should have linebreaks in there, to make it more readable, like so:
<cfif (not isdefined("URL.room") or URL.room EQ "")
and (not isdefined("URL.system" or URL.system EQ "")
and (not isdefined("URL.date") or URL.date EQ "")
>
And I would be more inclined to write it like this:
<cfif NOT
( ( isDefined('Url.Room') AND Len(Url.Room) )
OR ( isDefined('Url.System') AND Len(Url.System) )
OR ( isDefined('Url.Date') AND Len(Url.Date) )
)>
Because that's much more readable, and makes it more obvious that each row is checking the same thing.
That is assuming I was doing this in a single IF statement, anyway.
If you start getting lots of conditions to check, you might want to consider doing something like this instead:
<cfset FieldList = "Room,System,Date" />
<cfset AllFieldsValid = true />
<cfloop index="Field" list="#FieldList#">
<cfif NOT ( StructKeyExists(Url,Field) AND Len(Url[Field]) )>
<cfset AllFieldsValid = false />
<cfbreak/>
</cfif>
</cfloop>
<cfif AllFieldsValid>
...
Which might look intimidating at first, but is much easier to maintain - you just add a new item to FieldList (and you may already have a variable which serves that purporse).
Anyway, hopefully all this helps - let me know if any questions on it.
I'd prefer...
<cfparam name="URL.room" default="">
<cfparam name="URL.system" default="">
<cfparam name="URL.date" default="">
<cfif len(URL.room) EQ 0 and len(URL.system) EQ 0 and len(URL.date) EQ 0>
...
</cfif>
Or if you're comfortable with mixing non-boolean functions and boolean expression
<cfif len(URL.room) and len(URL.system) and len(URL.date)>
...
</cfif>
replace the = with eq
In CFML the comparison operators use characters rather than symbols:
== EQ
!= NEQ
> GT
>= GTE
< LT
<= LTE
Similarly with boolean operators:
! NOT
&& AND
|| OR
You can still use the traditional symbols in CFScript mode.
Also worth mentioning that Railo, an alternative CFML engine to Adobe ColdFusion, allows you to use the symbols in tag-based code, if there is no ambiguity with closing tag (e.g. the condition is wrapped in parentheses).
#Henry:
<cfif len(URL.room) EQ 0 and len(URL.system) EQ 0 and len(URL.date) EQ 0>
...
</cfif>
Shorter:
<CFIF Len(URL.room) AND Len(URL.system) and Len(URL.date)>
Len() is better than EQ ""
You need to think your logic through a bit.
You can't check to see if room is an empty string if it is undefined.
Probably what you really need is :
If (structkeyexist(URL,"room") and (Len(URL.room) eq 0 or URL.room eq 'blah'))
Do something
Else
Do something else
I'm afraid stackoverflow cuts off your example condition on my phone, but hopefully this illustrates what you need to do.

When should I use # in ColdFusion?

This has been one of the biggest obstacles in teaching new people ColdFusion.
When to use # is ambiguous at best. Since using them doesn't often create a problem it seems that most people gravitate to using them too much.
So, what are the basic rules?
I think it may be easier to say where NOT to use #. The only place is in cfif statements, and cfset statements where you are not using a variable to build a string in quotes. You would need to use the # sign in almost all other cases.
Example of where you are not going to use it:
<cfset value1 = 5>
<cfset value2 = value1/>
<cfif value1 EQ value2>
Yay!!!
</cfif>
<cfset value2 = "Four plus one is " & value1/>
Examples of where you will use #:
in a cfset where the variable is surrounded by quotes
<cfset value1 = 5>
<cfset value2 = "Four plus one is #value1#"/>
the bodies of cfoutput, cfmail, and cffunction (output="yes") tags
<cfoutput>#value2#</cfoutput>
<cfmail to="e#example.com" from="e#example.com" subject="x">#value2#</cfmail>
<cffunction name="func" output="yes">#value2#</cffunction>
in an attribute value of any coldfusion tag
<cfset dsn = "myDB"/>
<cfquery name="qryUsers" datasource="#dsn#">
<cfset value1 = 5>
<cfset value2 = 10/>
<cfloop from="#value1#" to="#value2#" index="i">
<cfqueryparam value="#value1#" cfsqltype="cf_sql_integer"/>
EDIT:
One oddball little thing I just noticed that seems inconsistent is conditional loops allow the variable name to be used with and without # signs.
<cfset value1 = 5>
<cfloop condition = "value1 LTE 10">
<cfoutput>#value1#</cfoutput><br>
<cfset value1 += 1>
</cfloop>
<cfset value1 = 5>
<cfloop condition = "#value1# LTE 10">
<cfoutput>#value1#</cfoutput><br>
<cfset value1 += 1>
</cfloop>
Here's what Adobe has to say about it:
Using number signs
String interpolation:
<cfset name = "Danny" />
<cfset greeting = "Hello, #name#!" />
<!--- greeting is set to: "Hello, Danny!" --->
Auto-escaped string interpolation in cfquery:
<cfset username = "dannyo'doule" ?>
<cfquery ...>
select u.[ID]
from [User] u
where u.[Username] = '#username#'
</cfquery>
<!--- the query is sent to the server (auto-escaped) as: --->
<!--- select u.[ID] from [User] u where u.[Username] = 'dannyo''doule' --->
<!--- note that the single-quote in the username has been escaped --->
<!--- by cfquery before being sent to the database server --->
Passing complex arguments/attributes in CFML:
<cfset p = StructNew() />
<cfset p.firstName = "Danny" />
<cfset p.lastName = "Robinson" />
<cfmodule template="modules/view/person.cfm" person="#p#">
<!--- the variable Attributes.person will be --->
<!--- available in modules/view/person.cfm --->
Passing complex arguments requires # signes only in CFML, not CFScript. In addition, you can pass any kind of value: simple values, arrays, structs, cfcomponents, cffunctions, java objects, com objects, etc.
In all these cases, the text between the # signs does not have to be the name of a variable. In fact, it can by any expression. Of course, for string interpolation, the expression must evaluate to a simple value, but for argument/attribute passing in CFML, the expression may evaluate to any complex value as well.
The #...# syntax allows you to embed an expression within a string literal. ColdFusion is unfortunately pretty inconsistent about what's a string and what's an expression. Jayson provided a good list of examples of when to use (or not use) #s.
At the risk of sounding like a wise-guy, a rule of thumb is: use # around variables or expressions only when not doing so doesn't yield the correct result. Or: if you don't need them, don't use them.
I like Jayson's answer though.
Let's start by assuming you aren't talking about cfoutput tags, cause then the answer is always, elsewhere in your code, if you are inside of quotation marks, then need to use # symbols if it's possible to actually type the value that is going to be used...so if you are in a cfloop tag setting the 'to' attribute, you could easily type 6, but if you want to use a variable you need to use the # symbols. Now if you are in a cfloop tag setting the query parameter, there is no way you could actually type the query into that attribute, there is no way to type a query, so no # symbols are needed.
Likewise in a cfdump tag, you can dump static text, so if you want to dump the contents of a variable, then you will need to use a # symbol. This problem is generally self-correcting, but I feel your pain, your students are probably frustrated that there is no "ALWAYS USE THEM" or "NEVER USE THEM" approach...sadly this isn't the case, the only thing that is true, is only one way inside of quotation marks is going to be correct. So if it isn't working look at it hard and long and think to yourself: "Could I type that value out instead of using the value contained in that variable?" If the answer is no, then the # symbols won't be needed, otherwise get your # character foo on.