Ответы:
Я использовал следующее с большим успехом:
(["'])(?:(?=(\\?))\2.)*?\1
Он также поддерживает вложенные кавычки.
Для тех, кто хочет глубже объяснить, как это работает, вот объяснение от пользователя ephemient :
([""'])
сопоставить цитату;((?=(\\?))\2.)
если существует обратная косая черта, сожрать ее и, если это произойдет, сопоставить символ;*?
совпадать много раз (не жадно, чтобы не съесть заключительную цитату);\1
соответствовать той же цитате, которая использовалась для открытия.
"foo\"
. Трюк с заглядыванием в будущее делает ?
квантификатор притяжательным (даже если аромат регулярного выражения не поддерживает ?+
синтаксис или атомарную группировку)
(["'])(?:\\.|[^\\])*?\1
В общем, вам нужен следующий фрагмент регулярного выражения:
"(.*?)"
Это использует не жадные *? оператор, чтобы захватить все до, но не включая следующую двойную кавычку. Затем вы используете языковой механизм для извлечения сопоставленного текста.
В Python вы можете сделать:
>>> import re
>>> string = '"Foo Bar" "Another Value"'
>>> print re.findall(r'"(.*?)"', string)
['Foo Bar', 'Another Value']
"hello \" world"
"(.*?(?<!\\))"
Я бы пошел на:
"([^"]*)"
[^ «] Является регулярным выражением для любого символа , кроме ' » '
Причины , я использую это за отсутствие жадных многих операторов в том , что я должен продолжать смотреть , что только , чтобы убедиться , что я получаю это исправить.
Давайте рассмотрим два эффективных способа работы с экранированными кавычками. Эти шаблоны не предназначены для того, чтобы быть краткими и эстетичными, но должны быть эффективными.
Эти способы используют различение первых символов для быстрого поиска кавычек в строке без затрат на чередование. (Идея заключается в быстром отбрасывании символов, которые не являются кавычками, без проверки двух ветвей чередования.)
Содержимое между кавычками описывается с помощью развернутого цикла (вместо повторного чередования), чтобы быть более эффективным: [^"\\]*(?:\\.[^"\\]*)*
Очевидно, что для работы со строками, у которых нет сбалансированных кавычек, вы можете вместо этого использовать собственнические квантификаторы: [^"\\]*+(?:\\.[^"\\]*)*+
или обходной путь, чтобы эмулировать их, чтобы предотвратить слишком большой возврат. Вы также можете выбрать, чтобы цитируемая часть могла быть открывающей кавычкой до следующей (неэкранированной) кавычки или до конца строки. В этом случае нет необходимости использовать собственнические квантификаторы, нужно только сделать последнюю цитату необязательной.
Обратите внимание: иногда кавычки не экранируются с помощью обратной косой черты, а повторяются. В этом случае подшаблон содержимого выглядит так:[^"]*(?:""[^"]*)*
Шаблоны избегают использования группы захвата и обратной ссылки (я имею в виду что-то вроде (["']).....\1
) и используют простое чередование, но с ["']
самого начала, в факторе.
Perl нравится:
["'](?:(?<=")[^"\\]*(?s:\\.[^"\\]*)*"|(?<=')[^'\\]*(?s:\\.[^'\\]*)*')
(обратите внимание, что (?s:...)
это синтаксический сахар для включения режима точек / однолинейных внутри группы без захвата. Если этот синтаксис не поддерживается, вы можете легко включить этот режим для всего шаблона или заменить точку на [\s\S]
)
(Способ написания этого шаблона полностью «ручной» и не учитывает возможную внутреннюю оптимизацию движка)
ECMA скрипт:
(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')
POSIX расширен:
"[^"\\]*(\\(.|\n)[^"\\]*)*"|'[^'\\]*(\\(.|\n)[^'\\]*)*'
или просто:
"([^"\\]|\\.|\\\n)*"|'([^'\\]|\\.|\\\n)*'
/pattern/
без экранирования чего-либо (вместо обозначения объекта new RegExp("(?=[\"'])(?:\"[^\"\\\\]*...");
)
s
здесь: (?s:
и если вы положили (?s)
где-то в шаблоне.
RegEx принятого ответа возвращает значения, включая их окружающие кавычки: "Foo Bar"
и "Another Value"
как совпадения.
Вот RegEx, которые возвращают только значения между кавычками (как спрашивал спрашивающий):
Только двойные кавычки (используйте значение группы захвата # 1):
"(.*?[^\\])"
Только одинарные кавычки (используйте значение группы захвата # 1):
'(.*?[^\\])'
Оба (используйте значение группы захвата № 2):
(["'])(.*?[^\\])\1
-
Вся поддержка избежала и вложенных кавычек.
src="(.*)"
но, очевидно, он выбирал все до последнего ", ваш REGEX, однако, выбрал только содержимое src =" ", но я не понял, как?
В частности, ни один из этих ответов не приводит к регулярному выражению, где возвращаемое совпадение - это текст внутри кавычек, что и требуется. MA-Madden пытается, но получает только внутренний матч как захваченную группу, а не весь матч. Один из способов сделать это:
(?<=(["']\b))(?:(?=(\\?))\2.)*?(?=\1)
Примеры этого можно увидеть в этой демонстрации https://regex101.com/r/Hbj8aP/1
Ключевым моментом здесь является позитивный взгляд в начале (the ?<=
) и позитивный взгляд в конце (the ?=
). Смотритель смотрит за текущим символом, чтобы проверить кавычку, если он найден, то начните с него, а затем с помощью предпросмотра проверяется следующий символ на кавычку и, если он найден, останавливается на этом символе. Группа lookbehind (the ["']
) заключена в квадратные скобки, чтобы создать группу для каждой найденной цитаты в начале, затем она используется в конце lookahead, (?=\1)
чтобы убедиться, что она останавливается только тогда, когда находит соответствующую цитату.
Единственное другое осложнение заключается в том, что поскольку предвидение на самом деле не потребляет конечную кавычку, она будет снова найдена начальным lookbehind, что приводит к совпадению текста между конечными и начальными кавычками в той же строке. Помещение границы слова в открывающую кавычку ( ["']\b
) помогает в этом, хотя в идеале я бы хотел пройти мимо, но я не думаю, что это возможно. Бит, позволяющий избегать символов в середине, я взял прямо из ответа Адама.
(["'])(?:(?=(\\?))\2.)*?\1
Вышеприведенная схема делает свою работу, но я обеспокоен ее характеристиками (это неплохо, но могло бы быть и лучше). Мой ниже это ~ 20% быстрее.
Шаблон "(.*?)"
просто неполный. Мой совет для всех, кто читает это, просто НЕ ИСПОЛЬЗУЙТЕ ЕГО !!!
Например, он не может захватить много строк (при необходимости я могу предоставить исчерпывающий контрольный пример), как показано ниже:
$ string = 'Как дела? Я в
\'
порядке, спасибо ';
Остальные так же хороши, как и выше.
Если вы действительно заботитесь о производительности и точности, начните с приведенного ниже:
/(['"])((\\\1|.)*?)\1/gm
В моих тестах она охватывала все строки, которые я встречал, но если вы найдете что-то, что не работает, я с удовольствием обновлю это для вас.
Проверьте мой шаблон в онлайн-тестере регулярных выражений .
Мне понравилось решение Eugen Mihailescu, позволяющее сопоставлять содержимое между кавычками, в то же время позволяя избегать кавычек. Тем не менее, я обнаружил некоторые проблемы с экранированием и предложил следующее регулярное выражение, чтобы исправить их:
(['"])(?:(?!\1|\\).|\\.)*\1
Он делает свое дело и все еще довольно прост и прост в обслуживании.
Демо (с некоторыми другими тестами; не стесняйтесь использовать и расширять его).
PS: Если вы просто хотите , содержания между кавычками в полном матче ( $0
), и не боится использование производительности Пенальти:
(?<=(['"])\b)(?:(?!\1|\\).|\\.)*(?=\1)
К сожалению, без кавычек в качестве якорей мне пришлось добавить границу, \b
которая не очень хорошо подходит для пробелов и несловарных символов после начальной кавычки.
Или измените исходную версию, просто добавив группу и извлекая строковую форму$2
:
(['"])((?:(?!\1|\\).|\\.)*)\1
PPS: Если вы сосредоточены исключительно на эффективности, используйте решение Casimir et Hippolyte ; это хорошо.
-
, как в координатах долготы.
Эта версия
контролирует возврат
/(["'])((?:(?!\1)[^\\]|(?:\\\\)*\\[^\\])*)\1/
БОЛЬШЕ ОТВЕТОВ! Вот решение, которое я использовал
\"([^\"]*?icon[^\"]*?)\"
TLDR;
замените значок слова на то, что вы ищете в указанных цитатах и вуаля!
Как это работает, он ищет ключевое слово и не заботится о том, что еще между кавычками. Например:
id="fb-icon"
id="icon-close"
id="large-icon-close"
регулярное выражение ищет знак кавычки, "
затем ищет любую возможную группу букв, которая не может быть найдена "
до тех пор, пока не найдет, icon
и любую возможную группу букв, которых нет, "
затем ищет закрывающую"
name="value"
с, name={"value"}
так как регулярное выражение этого ответа возвращает icon
/ value
в качестве второй группы (в отличие от принятого ответа). Найти : =\"([^\"]*?[^\"]*?)\"
Заменить :={"$1"}
Мне понравилась более обширная версия Axeman, но у меня возникли некоторые проблемы (например, она не подходила)
foo "string \\ string" bar
или
foo "string1" bar "string2"
правильно, поэтому я попытался это исправить:
# opening quote
(["'])
(
# repeat (non-greedy, so we don't span multiple strings)
(?:
# anything, except not the opening quote, and not
# a backslash, which are handled separately.
(?!\1)[^\\]
|
# consume any double backslash (unnecessary?)
(?:\\\\)*
|
# Allow backslash to escape characters
\\.
)*?
)
# same character as opening quote
\1
string = "\" foo bar\" \"loloo\""
print re.findall(r'"(.*?)"',string)
просто попробуйте, работает как шарм !!!
\
указывает на пропуск символа
" foo bar" "loloo"
. Я подозреваю , что вы имели в виду , чтобы обернуть , что в сыром строку , как вы делали с регулярным выражением: r'"\" foo bar\" \"loloo\""'
. Пожалуйста, используйте отличные возможности форматирования SO, когда это уместно. Это не просто косметика; мы буквально не можем сказать, что вы пытаетесь сказать, если вы их не используете. И добро пожаловать в Stack Overflow !
echo 'junk "Foo Bar" not empty one "" this "but this" and this neither' | sed 's/[^\"]*\"\([^\"]*\)\"[^\"]*/>\1</g'
Это приведет к:> Foo Bar <> <> но это <
Здесь я показал результирующую строку между> <для ясности, также используя не жадную версию с этой командой sed, мы сначала выбрасываем мусор до и после этого "", а затем заменяем его на часть между "" и окружить это> <'s.
От Грега Х. я смог создать это регулярное выражение в соответствии со своими потребностями.
Мне нужно было соответствовать определенное значение, которое было квалифицировано, будучи внутри кавычек. Это должно быть полное совпадение, никакое частичное совпадение не должно вызывать попадание
Например, «test» не может соответствовать «test2».
reg = r"""(['"])(%s)\1"""
if re.search(reg%(needle), haystack, re.IGNORECASE):
print "winning..."
охотник
Если вы пытаетесь найти строки, которые имеют только определенный суффикс, такой как синтаксис точки, вы можете попробовать это:
\"([^\"]*?[^\"]*?)\".localized
Где .localized
суффикс?
Пример:
print("this is something I need to return".localized + "so is this".localized + "but this is not")
Это будет захватывать "this is something I need to return".localized
и "so is this".localized
нет "but this is not"
.
Дополнительный ответ для подмножества кодеров Microsoft VBA только один использует библиотеку, Microsoft VBScript Regular Expressions 5.5
и это дает следующий код
Sub TestRegularExpression()
Dim oRE As VBScript_RegExp_55.RegExp '* Tools->References: Microsoft VBScript Regular Expressions 5.5
Set oRE = New VBScript_RegExp_55.RegExp
oRE.Pattern = """([^""]*)"""
oRE.Global = True
Dim sTest As String
sTest = """Foo Bar"" ""Another Value"" something else"
Debug.Assert oRE.test(sTest)
Dim oMatchCol As VBScript_RegExp_55.MatchCollection
Set oMatchCol = oRE.Execute(sTest)
Debug.Assert oMatchCol.Count = 2
Dim oMatch As Match
For Each oMatch In oMatchCol
Debug.Print oMatch.SubMatches(0)
Next oMatch
End Sub
Для меня сработало это:
|([\'"])(.*?)\1|i
Я использовал в предложении, как это:
preg_match_all('|([\'"])(.*?)\1|i', $cont, $matches);
и это сработало отлично.
Все ответы выше хороши .... за исключением того, что они НЕ поддерживают все символы Юникода! на ECMA Script (Javascript)
Если вы являетесь пользователем Node, вы можете захотеть модифицированную версию принятого ответа, которая поддерживает все символы Юникода:
/(?<=((?<=[\s,.:;"']|^)["']))(?:(?=(\\?))\2.)*?(?=\1)/gmu
Попробуй здесь .
? The preceding token is not quantifiable