自动完成功能的正则表达式

3
我正在编写一个带有自动完成功能的搜索栏,该功能连接到一个端点。我使用正则表达式来确定在搜索栏中键入查询时我所处的“上下文”。这三个上下文是“属性”、“值”和“操作符”。允许使用的两个操作符是“AND”和“OR”。以下是一个示例查询的示例。

颜色:蓝色 AND 大小:“女士大号”(<--多个单词的值或属性名称用引号括起来)

当您在Blue后输入一个空格,并且用户开始输入“A/AN/AND/O/OR”时,我需要我的正则表达式进行匹配。一旦他们在操作符后输入了一个空格,我就需要停止匹配。
这是我想出来的表达式。
const contextIsOperator = /[\w\d\s"]+: *[\w\s\d"]+ [\w]*$/

在"Blue,"之后加上一个空格后可以匹配,但是在"Blue,"之后的任何其他字符都可以匹配。如果将表达式中的最后一个*替换为+,那么当我在"Blue"之后放置一个空格并且手动输入其中一个运算符时,它可以工作,但如果只是在"Blue"之后有一个空格,则不能工作。

我脑海中的模式用文字写成如下:

  1. 一个或多个字符/数字/空格/引号组成的组
  2. 后跟冒号
  3. 后跟一个可选空格
  4. 后跟另一个由一个或多个字符/数字/空格/引号组成的组
  5. 值后面跟一个空格
  6. 后面跟一个或多个字符(这是操作符)

我该怎么解决这个问题?


在提问时,请将所有代码放入代码块中:通常,通过缩进所有代码行4个空格或使用3个反引号(`` )来包围代码块。对于与非代码位于同一行的内联代码,请在每侧使用单个反引号(`)。 - CertainPerformance
你最好采用词法分析器和语法分析器来完成这个任务。但是总会有人能帮助你使用正则表达式实现它。 - Todd Chaffee
1
不必同时使用\w\d,因为数字已经包含在\w中了。 - Barmar
1
当你说“characters”时,我想你是指“letters”吗?“characters”意味着任何类型的字符。 - Barmar
2
由于“Women's Large”中的撇号不是字母、数字、空格或引号,因此它无法匹配。 - Barmar
显示剩余2条评论
4个回答

1
[\w]*替换为仅匹配ANDOR或它们的前缀之一的内容。然后,您可以使用?使其变为可选项。
[\w\s"]+: *[\w\s"]+ (A|AN|AND|O|OR)?$

演示

请注意,尺码:女大号不能匹配此内容,因为撇号不在\w中;它只匹配字母、数字和下划线。您需要将您想要允许在这些字段中使用的任何其他标点符号添加到字符集中。


即使使用提供的示例(甚至去掉撇号),这个解决方案也不起作用。 $ 表示字符串的结尾,因此您需要指定 AND/OR 在字符串的末尾。另外,为什么要使用 (A|AN|AND|O|OR)?这将匹配无效的运算符(ANAO)。 - c1moore

0

就像你所说的,你的语言不够确定性,无法用正则表达式进行正确建模。尽管如此,你可以采取两种方法:

  1. 要求所有值(在冒号后和运算符之前的内容)都必须用引号括起来
  2. 构建一个简单的状态机,可以更智能地解析数据。(谷歌有限状态机解析器)

如果你选择使用第一种方法,你可以使用以下正则表达式:

^(("?[\w\s]+"?): ?("[\w\s']+")( (AND|OR) )?)+$

我可以解释不同的组件,但是regex101已经用非常好的视觉和细节为我解释了。


0

编辑:这是最终版本,请检查单元测试此处

const regex = /((("[\w\s"'']+(?="\b))"|[\w"'']+):\s?(("[\w\s"'']+(?="\b))"|[\w"'']+)\s(AND|OR)(?=\b\s))+/

这个怪物应该匹配 (注意:引用的键/值必须使用双引号):

Color: Blue AND "Size5":"Women's Large"
"weird KEy":regularvalue OR otherKey: "quoted value"

这与他提供的示例不完全匹配:https://regex101.com/r/g5EMqM/1 - c1moore
@c1moore,我已经修复了,谢谢!原来的正则表达式只需要在末尾加一个额外的空格,但这个新的好多了。https://regex101.com/r/2THj9F/4/tests - yaas

0

给你,试试这个

^(?:"[^"]*"|[^\s:]+):[ ](?:"[^"]*"|[^\s:]+)[ ](?:A(?:N(?:D(?:[ ](*SKIP)(?!))?)?)?|O(?:R(?:[ ](*SKIP)(?!))?)?)?

https://regex101.com/r/neUQ0g/1

解释

 ^                             # BOS
 (?:                           # Attribute
      "
      [^"]* 
      "
   |  
      [^\s:]+ 
 )
 :
 [ ] 
 (?:                           # Value
      "
      [^"]* 
      "
   |  
      [^\s:]+ 
 )
 [ ]                           # Start matching after Attribute: Value + space
 (?:                           # Operator
      A
      (?:
           N
           (?:
                D 
                (?:                           # Stop matching after 'AND '
                     [ ] 
                     (*SKIP) 
                     (?!)
                )?
           )?
      )?
   |  
      O 
      (?:
           R 
           (?:                           # Stop matching after 'OR '
                [ ] 
                (*SKIP)                    
                (?!)
           )?
      )?
 )?

哇!这太棒了。感谢您抽出时间编写如此复杂的表达式! - Sean San
@SeanSan - 一点也不复杂。 - user557597

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接