3

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!

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

1 Comment

note that this will return TRUE for s <- "P1+P2$P3" maybe if you change the split param to only contain operator then this case will fail ie strsplit(s,"[/+*]")
2

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.

5 Comments

Thank you for your reply. What should the split argument in strsplit be? Also, do you think this will work for Allowed items with length >1 (eg "P1")?
@emantz the argument is the command which your user gave as input - for example if the user gave the string ` "P1+P2/2"`, you enter it into the function, and thats it.
@emantz I also just noticed I missed a bracket, now its fixed.
I meant the split argument in strsplit(string): Error in strsplit(string) : argument "split" is missing, with no default
I think I need to add [[1]] after temp, since it is a list: So, it works but only with Allowed elements of 1 character. For example, with Allowed = c("+","-","*", "/","P1","n","X"), Vcheck(string="X+P1"), will return FALSE.
1

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.

6 Comments

one slight improvement if OP has no knowledge whatsoever about regex is to take the operators as string then paste0 the brackets
@AbdessabourMtk. That still could be dangerous if they did something like "^*+". I'm not sure if there's a function that will automatically escape "special" character in a regular expression, but if one exists that is a good idea.
if you paste0('[\\', operators, ']') would work even if the first operator is + or * ....
following your edit better use collapse='' as they're already inside a character class
@AbdessabourMtk I just changed it from a character class to a group to allow for multi-character operators like %% or something. But thanks for the suggestion.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.