Thomas said:
RobG wrote:
To build the white/black list, use a string of characters and the
RegExp() function as a constructor, e.g. if you want to disallow the
letter 'a' in a string, then:
var re = new RegExp('a');
will create a regular expression that can be used to match the letter
'a' anywhere, [...]
While there is not much point in using the RegExp() constructor instead
of a Regular Expression literal when the expression is invariant.
My understanding of the request is that the string *is* variant. The OP
wishes to build a list of characters to allow/disallow, I presumed it
would not be hard-coded - though it might be built that way at the
server where the value is extracted from a database and the appropriate
value hard-coded into the script.
But I supposed that the value would written to some variable, which is
then accessed by the script, e.g.
var blackList = '$%#';
and then later:
var re = new RegExp('[' + blacklist + ']');
of a Regular Expression literal when the expression is invariant. As was
discussed here recently, efficiency and compatibility are seldom an issue:
As for efficiency, the RegExp object created by a RegExp literal is created
before execution, and the literal is then merely a reference to that
object. The RegExp object is not recreated by repeated use of the same
literal (say, in a loop). (Which must be considered regarding efficiency,
though, since this will create a new RegExp object always if the expression
differs, unconditionally. Even if the object is used only when a certain
condition applies.)
Quite true, I was addressing efficiency from the point of view of the
length of the expression. e.g. to allow only letters and digits, \w
will do the trick. To disallow only '@#$' then - [@#$] - is much
shorter than a list of everything else.
The difference in efficiency between using RegExp as a constructor and
using a literal in the above scenario is likely irrelevant (though I
understand your point and in general much prefer to use literals).
[...]
However, using the RegExp constructor removes and introduces a maintenance
problem. It removes the problem that Regular Expressions cannot span lines
because string concatenation serves the purpose. It introduces the problem
that one has to escape the expression twice: one time to avoid escape
sequences in the string literal, and again to have RegExp special
characters parsed as expression atoms instead.
Escaping characters is always an issue, especially if multi-line input
is accepted. Should new lines & line feeds be allowed? The solution is
for the OP to learn about matching characters and apply that to their
particular circumstance.
[...]
var re = /a/;
and the like certainly suffices here.
Probably a result of my trivial example - a better example is below.
As I final note, I want to add that if special features of Regular
Expressions compared to strings are not used, it is probably more
efficient not to use Regular Expressions at all. Instead of writing
if (re.test(someString))
using the RegExp() constructor or the above RegExp object initializer,
it is probably more efficient to write
if (someString.indexOf("a") > -1)
If the need was a test for a specific character, then that would be
fine. Maybe you could use it with a loop to go through each character
in the black list, but how many characters/loops would it take before a
regular expression was faster?
The following example may be better:
<script type="text/javascript">
function checkList(blID, strID)
{
var blackList = document.getElementById(blID).value;
var inString = document.getElementById(strID).value;
var re = new RegExp('[' + blackList + ']');
document.getElementById('xx').innerHTML = re.test(inString);
}
</script>
<label for="blackList">Blacklist characters:<input
type="text" id="blackList" value="\^\]$#@"></label><br>
<label for="inputText">String to check:<input
type="text" id="inputText" value="Cost: $6"></label>
<input type="button" value="Check input with blacklist"
onclick="checkList('blackList','inputText');">
<div>Result: <span id="xx" style="font-weight: bold;">
<i>no check done yet...</i></span></div>
If new lines, line feeds, etc. need to be tested too, use a textarea
instead of a text input for the input string. Variations on how
browsers represent new lines may need to be accommodated too.