从正则表达式匹配中过滤出一个表达式

时间:2018-09-26 13:55:39

标签: regex filter

我有一个正则表达式查询,该查询对大多数输入模式都适用,但很少。 我有的正则表达式查询是

(define (list-replace li)
(cond
((null? li) li)

((and (= (modulo (car li) 3) 0) (= (modulo (car li) 5) 0)) (cons "T-ICE" (list-replace(cdr li))))

((= (modulo (car li) 3) 0) (cons "T" (list-replace(cdr li))))

((= (modulo (car li) 5) 0) (cons "ICE" (list-replace(cdr li))))

(else (cons (car li) (list-replace(cdr li))))))

我想从输入字符串中过滤出某种类型的表达式,即除了输入字符串的最后一个字符外,每个破折号(-)都应由两个单独的整数包围,即(integer)(dash)(integer)

不允许两个破折号共享3个整数,即使它们的两边都有("(?!([1-9]{1}[0-9]*)-(([1-9]{1}[0-9]*))-)^(([1-9]{1}[0-9]*)|(([1-9]{1}[0-9]*)( |-|( ?([1-9]{1}[0-9]*))|(-?([1-9]{1}[0-9]*)){1})*))$") 这样的整数。

如果破折号是输入的最后一个字符,后跟整数,该整数是可接受的输入,例如(integer)(dash)(integer)(dash)(integer)

此外,不允许连续两个破折号。上述任何一种格式之间都可以有空格。

要给出要点,请在我的输入字符串中使用这些破折号来提供范围。 我要过滤掉的一些表达式示例是

  

(integer)(dash)(end of the string)1-5-101 - 5 - 101 - - 5

更新-有些规则将驱动输入字符串。我的工作是确保仅允许输入遵循格式的那些字符串。格式规则为-

 1.用空格(‘’)分隔数字。但是虚线不需要空格。例如,“ 10 20-30”或“ 10 20-30”都是有效值。

 2.虚线('-')用于设置范围(从,到)。它还可以用于设置到作业队列列表的末尾。例如,“ 100-150 200-250 300-”是有效值。

3.不允许没有起始作业编号的虚线。例如,不允许使用“ -10”。

谢谢

2 个答案:

答案 0 :(得分:2)

您可以使用:

^(?:(?:[1-9][0-9]*[ ]?-[ ]?[1-9][0-9]*|[1-9][0-9]*)(?: (?:[1-9][0-9]*[ ]?-[ ]?[1-9][0-9]*|[1-9][0-9]*))*(?: [1-9][0-9]*-)?|[1-9][0-9]*-?)[ ]*$

Regex demo

说明

  • ^声明字符串的开头
  • (?:非捕获组
    • (?:非捕获组
      • [1-9][0-9]*[ ]?-[ ]?[1-9][0-9]*匹配数字> 0,可选空格,破折号,可选空格和数字>0。为了清楚起见,该空格位于字符类[ ]
      • |
      • [1-9][0-9]*匹配号码> 0
    • )关闭非捕获组
    • (?:[ ]非捕获组,后跟一个空格
      • (?:非捕获组
        • [1-9][0-9]*[ ]?-[ ]?[1-9][0-9]*匹配数字> 0,可选空格,破折号,可选空格和数字> 0。
        • |
        • [1-9][0-9]*匹配号码> 0
      • )关闭非捕获组
    • )*关闭非捕获组并重复零次或更多次
    • (?: [1-9][0-9]*-)?可选部分,与空格匹配,后接数字> 0
    • |
    • [1-9][0-9]*-?匹配一个数字> 0,后跟一个可选的破折号
  • )关闭非捕获组
  • [ ]*$匹配零次或多次空格,并断言字符串的结尾

注意,如果您想将一个空格而不是可选空格匹配零次或多次,则可以将[ ]?更新为[ ]*。您可以将[1-9]{1}写为[1-9]

答案 1 :(得分:0)

更新后,问题变得相当复杂。由于正则表达式的某些部分可以重复使用多次,因此我可以自由地在Ruby中进行处理,然后对其进行清理。我将向您展示构建过程,以便可以理解正则表达式。 Ruby使用#{variable}进行正则表达式和字符串插值。

integer = /[1-9][0-9]*/
integer_or_range = /#{integer}(?: *- *#{integer})?/
integers_or_ranges = /#{integer_or_range}(?: +#{integer_or_range})*/
ending = /#{integer} *-/
regex = /^(?:#{integers_or_ranges}(?: +#{ending})?|#{ending})$/
#=> /^(?:(?-mix:(?-mix:(?-mix:[1-9][0-9]*)(?: *- *(?-mix:[1-9][0-9]*))?)(?: +(?-mix:(?-mix:[1-9][0-9]*)(?: *- *(?-mix:[1-9][0-9]*))?))*)(?: +(?-mix:(?-mix:[1-9][0-9]*) *-))?|(?-mix:(?-mix:[1-9][0-9]*) *-))$/

清理上面的正则表达式叶子:

^(?:[1-9][0-9]*(?: *- *[1-9][0-9]*)?(?: +[1-9][0-9]*(?: *- *[1-9][0-9]*)?)*(?: +[1-9][0-9]* *-)?|[1-9][0-9]* *-)$

如果愿意,可以将[0-9]替换为\d,但是由于您在问题中使用了[0-9]语法,因此我也将其用作答案。请记住,如果您将[0-9]替换为\d,则必须在字符串上下文中转义反斜杠。例如。 "[0-9]"等于"\\d"

您在问题中提到

  

上述任何格式之间都可以有空格。

我认为这意味着在实际内容之前或之后不允许有空格,只能在整数和-之间。

  • 有效:

    15 - 10

    1234 -

  • 无效:

    15 - 10

    123

如果不是这种情况,只需在开头和结尾处添加 *

^ *... *$

...是正则表达式的其余部分。

您可以在我的demo中测试正则表达式,但是从构建过程中应该可以清楚看到正则表达式的作用。

var
inputs = [
  '1-5-10',
  '1 - 5 - 10',
  '1 - - 5',
  '-5',
  '15-10',
  '15 - 10',
  '15      -          10',
  '1510',
  '1510-',
  '1510       -',
  '1510    ',
  '   1510',
  '  15 - 10',
  '10 20 - 30',
  '10 20-30',
  '100-150 200-250 300-',
  '100-150 200-250 300- ',
  '1-2526-27-28-',
  '1-25 26-2728-',
  '1-25 26-27 28-',
],

regex = /^(?:[1-9][0-9]*(?: *- *[1-9][0-9]*)?(?: +[1-9][0-9]*(?: *- *[1-9][0-9]*)?)*(?: +[1-9][0-9]* *-)?|[1-9][0-9]* *-)$/,

logInputAndMatch = input => {
  console.log(`input: "${input}"`);
  console.log(input.match(regex))
};

inputs.forEach(logInputAndMatch);