Reputation: 461
I am trying to set up a table where the users can insert formulas in the form of a string.
They are allowed to use only operators and given par names (eg, par.names<- c("P1", "P2", "P3")
)
I need to test if the formula is correct, by checking whether a user has used any other patterns.
For example P1+P2*P3
should be acceptable, while P1+P5*P$4
should return an error.
What would be the suggested way to do this?
Thank you!
Upvotes: 3
Views: 1801
Reputation: 206167
Here's one way, first, you define your variable names and then give a regular expression that would match your operators, then we can make a validater function
par.names<- c("P1", "P2", "P3")
operators <- "[*+]"
get_checker <- function(par.names, operatorsRE) {
function(x) {
nonops <- strsplit(x, operatorsRE)
sapply(nonops, function(x) all(x %in% par.names))
}
}
checker <- get_checker(par.names, operators)
We just use an enclosure to keep everything in a tidy function. Then we can use that to validate input
input <- c("P1+P2*P3", "P1+P5*P$4")
checker(input)
# [1] TRUE FALSE
Here's a version that will allow you to pass an array of operators instead.
par.names<- c("P1", "P2", "P3")
operators <- c("^", "*","+")
get_checker <- function(par.names, operators) {
operatorsRE <- paste0("(", paste(Hmisc::escapeRegex(operators), collapse="|"),")")
function(x) {
nonops <- strsplit(x, operatorsRE)
sapply(nonops, function(x) all(x %in% par.names))
}
}
That way you can avoid regular expression quirks but this does use the Hmisc
package for a helper function.
Upvotes: 1
Reputation: 962
create a vector which holds strings of valid characters:
Allowed = c("+","-","*", "/","P","n","X")
write a function to check if any of the characters in the command are not allowed:
Vcheck = function(string){
temp = strsplit(string, "")
(((temp %in% Allowed) %>% sum) == length(temp)) %>% return
}
This should return 1 if it contains allowed character, and 0 if it contains a forbidden one. I trust you know how to write a function to return an error.
Upvotes: 2
Reputation: 101064
Maybe you can try the code below
all(unlist(strsplit(s,"[^[:alnum:]]")) %in% par.names)
Example
> s1 <- "P1+P2*P3"
> s2 <- "P1+P5*P$4"
> all(unlist(strsplit(s1,"[^[:alnum:]]")) %in% par.names)
[1] TRUE
> all(unlist(strsplit(s2,"[^[:alnum:]]")) %in% par.names)
[1] FALSE
Upvotes: 2