Regex для получения строки до появления специального символа в javascript - PullRequest
4 голосов
/ 19 июня 2020

У меня есть строка, которая выглядит, как показано ниже

str = "I have candy='4' and ice cream = 'vanilla'"

Я хочу, чтобы термины располагались слева от последнего =, и эти термины следует извлекать до появления другого =.

Итак, моя строка должна быть

leftOfEqual = "'4' and ice cream"

Другой пример

str = "I have candy='4' and ice cream = 'vanilla' and house='big'"

leftOfEqual = "'vanilla' and house"

Это мой regex в настоящее время

leftOfEqual = str.match(/\S+(?= *=)/)[0]

Но он смотрит на первый = и дает мне только ближайшее слово слева.

Как я могу это сделать?

ПРИМЕЧАНИЕ: В случае отсутствия присутствия = слева от последнего =, тогда я должен получить всю строку до начала.

Ответы [ 5 ]

4 голосов
/ 19 июня 2020

Использование split и slice для поиска предпоследней разделенной группы. lastIndexOf решение, просто поиск со спины. Найдите первый =, затем перейдите к следующему =, разделите их.

str = "I have candy='4' and ice cream = 'vanilla'"
console.log(
str.split('=').slice(-2)[0]
)

console.log(
str.slice(str.lastIndexOf('=',x=str.lastIndexOf('=')-1)+1,x<-1?undefined:x)
)

str = "and ice cream = 'vanilla'"
console.log(
str.split('=').slice(-2)[0]
)

console.log(
str.slice(str.lastIndexOf('=',x=str.lastIndexOf('=')-1)+1,x<-1?undefined:x)
)

str = "I have cand'4' and ice cream 'vanilla'"
console.log(
str.split('=').slice(-2)[0]
)

console.log(
str.slice(str.lastIndexOf('=',x=str.lastIndexOf('=')-1)+1,x<-1?undefined:x)
)
3 голосов
/ 19 июня 2020

Вероятно, вы можете попробовать:

.*=(.*)=.*|(.*)=.*

Объяснение приведенного выше регулярного выражения:

.* - соответствует всему за исключением новой строки перед символом = жадно .

= - соответствует = буквально.

=(.*)= - представляет группу захвата, захватывающую все в диапазоне =. Вы можете использовать несколько символов, если хотите, используя их как классы символов, например [=%#].

|(.*)=.* - представляет альтернативную группу захвата, представляющую левую часть знака равенства в в случае отсутствия = после последнего =.

$1$2 - Вы можете использовать это как вариант замены для замены всей строки требуемым выводом.

Вы можете найти демонстрацию вышеуказанного регулярного выражения в здесь.

image

const regex = /.*=(.*)=.*|(.*)=.*/g;
const str = `"I have candy='4' and ice cream = 'vanilla'"
I have candy='4' and ice cream = 'vanilla' and house='big'
Regex is fun
Regex is beauty =
Regex is awesome = test test test
`;
const subst = `$1$2`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
// You can use trim if you want to get rid of previous or after spaces.
console.log(result);

2 голосов
/ 19 июня 2020

В вашем текущем шаблоне \S+(?= *=) вы сопоставляете 1+ символов без пробелов и утверждаете, что то, что справа, является знаком равенства.

Вы также можете использовать группу захвата и сопоставить последний = в конец строки.

Если нет доступного значения группы 1, вернуть совпадение, соответствующее любому символу, кроме символа новой строки или =. В противном случае верните значение группы 1.

^(?:.*=([^\r\n=]+)=[^=\r\n]+$|[^\r\n=]+)

Объяснение

  • ^ Начало строки
  • .*= Соответствует любому символу кроме символа новой строки 0+ раз до последнего появления =
  • [^\s=]+ Соответствует любому символу, кроме - или пробельному символу
  • \s*=\s* Соответствует = между необязательными пробелами символы
  • ( Захват группа 1
    • [^\r\n=]+ Соответствует 1+ раз любому символу, кроме = или новой строки
  • ) Закрыть группу 1
  • =[^=\r\n]+$ Соответствует последнему = в конце строки.
  • | Или
  • [^\r\n=]+ Соответствует 1+ раз любому символу, кроме символа новой строки или =

Regex demo

const pattern = /^(?:.*=([^\r\n=]+)=[^=\r\n]+$|[^\r\n=]+)/;
[
  "I have candy='4' and ice cream = 'vanilla'",
  "I have candy='4' and ice cream = 'vanilla' and house='big'",
  "test test ='test test test'"
].forEach(s => {
  console.log(s.match(pattern)[1] || s.match(pattern)[0]);
});
2 голосов
/ 19 июня 2020

В конечном итоге, я думаю, вы могли бы просто использовать split и reverse с дополнительным trim:

str = "I have candy='4' and ice cream = 'vanilla' and house='big'"
leftOfEqual = str.split('=').reverse()[1].trim();
console.log(leftOfEqual)

Но если вы должны использовать regex, можно использовать такой шаблон, как:

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

См. Онлайн-демонстрация

  • [^=]+ - Отрицательный знак равенства, один или несколько раз
  • (?==[^=]*$) - Положительный просмотр вперед для знака равенства с последующим отрицанием знака равенства ноль или более раз до конца строки ancor.

enter image description here


Это также должно быть отмечено:

" Если слева от latest = нет наличия =, я должен получить всю строку до начала. "

1 голос
/ 19 июня 2020

Вы можете использовать поиск

const findData = (str) => {
  let data = str.match(/(?<==)([^=]+)(?==[^=]*$)/)
  return data ? data[1].trim() : ''
}

let str1 = "I have candy='4' and ice cream = 'vanilla' and house='big'"
let str2 = "I have candy='4' and ice cream = 'vanilla'"

console.log(findData(str1))
console.log(findData(str2))

// You can use split as well

console.log(str1.split('=').slice(-2)[0].trim())
console.log(str2.split('=').slice(-2)[0].trim())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...