RegEx для функции автозаполнения - PullRequest
4 голосов
/ 30 мая 2019

Я пишу строку поиска с функцией автозаполнения, которая подключена к конечной точке. Я использую регулярное выражение, чтобы определить «контекст», в котором я нахожусь внутри запроса, который я печатаю в строке поиска. Три контекста - это «атрибут», «значение» и «оператор». Допустимы два оператора «И» и «ИЛИ». Ниже приведен пример примера запроса.

Цвет: синий И Размер: "Большой женский" (<- значения из нескольких слов или имена атрибутов заключены в кавычки) </p>

Мне нужно, чтобы мое регулярное выражение совпадало после того, как вы поставили пробел после синего, и если пользователь начинает вводить "A / AN / AND / O / OR", мне нужно, чтобы оно совпадало. После того, как они поставили пробел после оператора, мне нужно, чтобы он прекратил сопоставление.

Это выражение, которое я придумал.

const contextIsOperator = /[\w\d\s"]+: *[\w\s\d"]+ [\w]*$/

Это совпадает, когда я ставлю пробел после "Blue", но соответствует всему, что я ставлю после этого. Если я заменю последний * в выражении на +, это сработает, когда я ставлю пробел после "Blue" * и начинают вручную вводить один из операторов, но не тогда, когда у меня просто пробел после "Синий".

Образец, который у меня в голове написан словами:

  1. группа из одного или нескольких символов / цифр / пробелов / кавычек
  2. , за которым следует двоеточие
  3. с последующим необязательным пробелом
  4. , за которым следует другая группа из одного или нескольких символов / цифр / пробелов / кавычек
  5. с пробелом (после значения)
  6. с последующим одним или несколькими символами (это оператор)

Как мне решить эту проблему?

Ответы [ 4 ]

2 голосов
/ 30 мая 2019

Замените [\w]* на что-то, что просто соответствует AND, OR или одному из их префиксов. Тогда вы можете сделать это необязательным с ?

[\w\s"]+: *[\w\s"]+ (A|AN|AND|O|OR)?$

DEMO

Обратите внимание, что Size: Women's Large не будет соответствовать этому, потому что апостроф не в \w; это соответствует только буквам, цифрам и подчеркиванию. Вам нужно будет добавить любые другие знаки препинания, которые вы хотите разрешить в этих полях, к набору символов.

1 голос
/ 30 мая 2019

Вот, пожалуйста, попробуйте это

^(?:"[^"]*"|[^\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)                    
                (?!)
           )?
      )?
 )?
1 голос
/ 30 мая 2019

Редактировать: это последний, проверьте юнит-тесты здесь

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

Это чудовище должно совпадать (NOTE: QUOTED KEYS/VALUES MUST BE DOUBLE QUOTED):

Color: Blue AND "Size5":"Women's Large"
"weird KEy":regularvalue OR otherKey: "quoted value"
0 голосов
/ 30 мая 2019

Ваш язык недостаточно детерминирован, чтобы его можно было смоделировать с помощью регулярного выражения. При этом есть 2 подхода, которые вы можете использовать:

  1. Требовать, чтобы все значения (вещи после : и перед оператором) были заключены в кавычки
  2. Создайте простой конечный автомат, который сможет более разумно анализировать данные. (Парсер конечного автомата Google)

Если вы решите использовать первый метод, вы можете использовать следующее регулярное выражение:

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

Я бы объяснил разные компоненты, но regex101 уже делает для меня действительно хорошие визуальные эффекты и детализацию.

...