正则表达式,可选(开头)括号,但右括号应该是强制性的

时间:2016-07-26 13:25:07

标签: javascript php regex

如果我创建了一个正则表达式,它允许用户在我的应用程序中制作公式。正则表达式我工作正常,但我希望用户使用开括号和右括号。

我目前的正则表达式是:

(
    ^[(N|R)]:   //START WITH N: OR R:

    (?:
        (?:
            [-.0-9]+|BT|PT|PN|PR  //ALLOW 48.934, BT, PT, PN OR PR
        )
        (?:
            \+|\*|\-|\/ //ALLOW OPERATORS /,*,+ and -
        )
    )+ //REPEAT x TIMES

    (?:
        [-.0-9]+|BT|PT|PN|PR //MUST END WITH 48.934, BT, PT, PN OR PR
    )

    (?:
        :V //ADD MANDATORY :V
    )

    (?:
        [-.0-9]+ //CLOSE REGEX WITH NUMBER
    )
)

正则表达式当前有效的几个示例:

N:0.3*BT/PN*PR:V1
N:2000+PN/BT:V0.5
R:BT*PN-500:V2

我希望正则表达式与()一起使用,目前它不是一些例子:

N:(2000+PN)/BT:V0.5
R:BT*(PN-500):V2

我已经读过积极和消极的前瞻,创建if / else结构,但我似乎无法找到适合我需要的逻辑。

非常感谢有人能引导我朝着正确的方向前进。

P.S。我正在使用javascript正则表达式引擎。

4 个答案:

答案 0 :(得分:1)

以下是正则表达式的修改版本,允许任意数量的匹配(但不是嵌套)的parens(请参阅regex101):

(?=
    [^()]*
    (\([^()]+\)[^()]*)*
    $
)

^[NR]:   //START WITH N: OR R:

(?:
    \(?(?:[-.0-9]+|BT|PT|PN|PR)\)? //ALLOW 48.934, BT, PT, PN OR PR
    [-+*\/]                        //ALLOW OPERATORS /,*,+ and -
    \(?(?:[-.0-9]+|BT|PT|PN|PR)\)? //ALLOW 48.934, BT, PT, PN OR PR
)+ //REPEAT x TIMES

(?:
    [-+*\/]                        //ALLOW OPERATORS /,*,+ and -
    (?:[-.0-9]+|BT|PT|PN|PR)       //ALLOW 48.934, BT, PT, PN OR PR
    \)?
)*`


:V //ADD MANDATORY :V
[-.0-9]+ //CLOSE REGEX WITH NUMBER

说明:

除了[(N|R)]和其他无关分组的一些清理之外,主要的变化是在一开始就添加一个积极的先行,以确保任何parens成对出现:

(?=
    [^()]*
    (\([^()]+\)[^()]*)*
    $
)

然后允许在每个数字或变量周围使用parens。

答案 1 :(得分:0)

首先,您应该更改RegEx ^[NR]:的第二行,因为[]之间几乎每个字符都是字面值。这也算作括号。

然后我需要让你失望,有一些使用lookaheads的条件,但是在我阅读时没有在JavaScript中。我不知道XRegExp,也许我们希望它可以做到这一点。 if-else应该是这样的:

(?(?=\()[^)]*))
基本语法:
(?(?=RegExp)then|else)

答案 2 :(得分:0)

我认为你可以使用这样的正则表达式:

/^[NR]:(([()0-9.-]+|BT|P[TNR])[*+/-]?)+:V[0-9.-]+$/

<强> [JavaScript Regex Demo]

PCRE版本中应该是:

/^[NR]:(([()0-9\.-]+|BT|P[TNR])[*+\/-]?)+:V[0-9\.-]+$/

注意:
[]用于匹配其中包含的单个字符,因此[NR]将匹配NR,而PT|PN|PR可以是P[TNR]。< / p>

答案 3 :(得分:0)

您不能直接使用括号,因为它已经对正则表达式有意义。因此,当您使用括号'('时,请使用'\('