Determine if a string is numeric: Difference between revisions
Content added Content deleted
(→{{header|Common Lisp}}: Read-time side effects are suppressed by nulling *read-eval*. Reader can signal error. Memory is not a concern because the input is in a string! So no need for a library.) |
|||
Line 243: | Line 243: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
If the input may be relied upon to not be malicious, then it may be ''read'' and the result checked for being a number. |
|||
<lang lisp>(defun numeric-string-p (string) |
|||
⚫ | |||
Lisp's reader can be used to read the printed representation of an object from a string, and then this object can be checked whether it is a number. |
|||
However, <code>read</code>[<code>-from-string</code>] parses more than just numbers, and some input can have side effects and/or large memory allocation. The [http://www.cliki.net/PARSE-NUMBER <code>parse-number</code>] library provides a numbers-only equivalent of <code>read</code>. |
|||
Read-time evaluation is suppressed by nulling out the special variable <code>*read-eval*</code>. This is necessary if the string came from an untrusted input, allowing an attacker to inject hash-dot syntax to evaluate an arbitrary expression. |
|||
A second detail requiring attention is that the reader can signal if it encounters EOF or bad syntax in the middle of an object. The <code>ignore-errors</code> macro catches conditions of type <code>error</code> and turns them into a <code>nil</code> return value, which here conveniently becomes an indicator that the input isn't a number: |
|||
<lang lisp>(defun numeric-string-p (string) |
<lang lisp>(defun numeric-string-p (string) |
||
(let ((*read-eval* nil)) |
|||
(handler-case (progn (parse-number:parse-number string) |
|||
⚫ | |||
t) ; parse succeeded, discard it and return true (t) |
|||
(parse-number::invalid-number () |
|||
nil))) ; parse failed, return false (nil)</lang> |
|||
=={{header|D}}== |
=={{header|D}}== |