Получите то, что находится в строке из одной кавычки, в другую [дубликат]

В принятом ответе есть некоторые существенные сторонники. Не рекомендуется использовать AsyncTask для сетей, если вы действительно не знаете, что вы делаете. Некоторые из нижних сторон включают в себя:

  • AsyncTask, созданный как нестатические внутренние классы, имеет неявную ссылку на охватывающий объект Activity, его контекст и всю иерархию View, созданную этим действием. Эта ссылка запрещает сборку Мусора, пока работа в фоновом режиме AsyncTask не завершится. Если соединение пользователя происходит медленно и / или загрузка велика, эти кратковременные утечки памяти могут стать проблемой - например, если ориентация изменяется несколько раз (и вы не отменяете выполнение задач), или пользователь переходит к вдали от Activity.
  • AsyncTask имеет разные характеристики выполнения в зависимости от платформы, на которой он выполняется: до уровня API 4 AsyncTasks выполняется последовательно на одном фоновом потоке; от уровня API 4 до уровня API 10, AsyncTasks выполняется в пуле до 128 потоков; начиная с уровня API 11, AsyncTask выполняется последовательно в одном фоновом потоке (если вы не используете перегруженный метод executeOnExecutor и поставляете альтернативный исполнитель). Код, который отлично работает при последовательном запуске на ICS, может прерываться при одновременном выполнении на Gingerbread, скажем, если у вас есть непреднамеренные зависимости от порядка выполнения.

Если вы хотите избежать кратковременной памяти утечки, имеют четко определенные характеристики выполнения на всех платформах и имеют базу для создания действительно надежной сетевой обработки, вы можете подумать:

  1. Использование библиотеки, которая хорошо справляется с этим для вас - есть хорошее сравнение сетевых библиотек в этом вопросе или
  2. Вместо использования Service или IntentService, возможно, с PendingIntent, чтобы вернуть результат через

Подход IntentService

Вниз:

  • Больше кода и сложности, чем AsyncTask, хотя не так много, как вы могли бы подумать.
  • Будет очереди запросов и запускать их в фоновом потоке single . Вы можете легко управлять этим, заменив IntentService на эквивалентную реализацию Service, возможно, как этот .
  • Ум, я не могу сейчас думать о других

Верхние стороны:

  • Избегает проблемы с кратковременной утечкой памяти
  • Если ваша активность перезапускается, полет он все равно может получить результат загрузки с помощью своего метода onActivityResult
  • Лучшая платформа, чем AsyncTask для создания и повторного использования надежного сетевого кода. Пример: если вам нужно сделать важную загрузку, вы можете сделать это с AsyncTask в Activity, но если пользовательский контекст отключит приложение для совершения телефонного вызова, система может убейте приложение до завершения загрузки. менее вероятно , чтобы убить приложение с активным Service.
  • Если вы используете свою собственную параллельную версию IntentService (например, такую, которую я связал выше), вы можете управляйте уровнем параллелизма через Executor.

Резюме реализации

Вы можете реализовать IntentService для выполнения загрузки на одном фоновом потоке довольно легко.

Шаг 1. Создайте IntentService для выполнения загрузки. Вы можете сказать, что загрузить с помощью Intent extra's, и передать ему значение PendingIntent, чтобы вернуть результат в Activity:

import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class DownloadIntentService extends IntentService {

    private static final String TAG = DownloadIntentService.class.getSimpleName();

    public static final String PENDING_RESULT_EXTRA = "pending_result";
    public static final String URL_EXTRA = "url";
    public static final String RSS_RESULT_EXTRA = "url";

    public static final int RESULT_CODE = 0;
    public static final int INVALID_URL_CODE = 1;
    public static final int ERROR_CODE = 2;

    private IllustrativeRSSParser parser;

    public DownloadIntentService() {
        super(TAG);

        // make one and re-use, in the case where more than one intent is queued
        parser = new IllustrativeRSSParser();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
        InputStream in = null;
        try {
            try {
                URL url = new URL(intent.getStringExtra(URL_EXTRA));
                IllustrativeRSS rss = parser.parse(in = url.openStream());

                Intent result = new Intent();
                result.putExtra(RSS_RESULT_EXTRA, rss);

                reply.send(this, RESULT_CODE, result);
            } catch (MalformedURLException exc) {
                reply.send(INVALID_URL_CODE);
            } catch (Exception exc) {
                // could do better by treating the different sax/xml exceptions individually
                reply.send(ERROR_CODE);
            }
        } catch (PendingIntent.CanceledException exc) {
            Log.i(TAG, "reply cancelled", exc);
        }
    }
}

Шаг 2: Зарегистрировать службу в manifest:


Шаг 3. Вызовите службу из Activity, передав объект PendingResult, который служба будет использовать для возврата результата:

PendingIntent pendingResult = createPendingResult(
    RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);

Шаг 4: Обращение результат в onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
        switch (resultCode) {
            case DownloadIntentService.INVALID_URL_CODE:
                handleInvalidURL();
                break;
            case DownloadIntentService.ERROR_CODE:
                handleError(data);
                break;
            case DownloadIntentService.RESULT_CODE:
                handleRSS(data);
                break;
        }
        handleRSS(data);
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Здесь доступен gigub-проект, содержащий полный рабочий проект Android-Studio / gradle здесь .

147
задан Alan Moore 15 March 2014 в 19:32
поделиться

18 ответов

Я с большим успехом использовал следующее:

(["'])(?:(?=(\\?))\2.)*?\1

Он поддерживает вложенные кавычки.

Для тех, кто хочет более глубокое объяснение того, как это работает, вот объяснение от пользователя ephemient :

([""']) соответствует цитате; ((?=(\\?))\2.), если существует обратная косая черта, сожрать ее, и происходит ли это, соответствует ли символ; *? соответствуют много раз (не жадному, чтобы не есть заключительная цитата); \1 соответствуют той же цитате, которая использовалась для открытия.

248
ответ дан Community 31 August 2018 в 21:54
поделиться

Эта версия

  • учитывает экранированные кавычки
  • управляет обратным трассированием
    /(["'])((?:(?!\1)[^\\]|(?:\\\\)*\\[^\\])*)\1/
    
6
ответ дан 2 revs, 2 users 91% 31 August 2018 в 21:54
поделиться
string = "\" foo bar\" \"loloo\""
print re.findall(r'"(.*?)"',string)

просто попробуйте это, работает как шарм !!!

\ указывает символ пропуска

2
ответ дан Alan Moore 31 August 2018 в 21:54
поделиться
echo 'junk "Foo Bar" not empty one "" this "but this" and this neither' | sed 's/[^\"]*\"\([^\"]*\)\"[^\"]*/>\1</g'

Это приведет к:> Foo Bar & lt;> & lt;>, но это & ​​lt;

Здесь я продемонстрировал строку результата между> & lt; s для ясности, также используя неживую версии с этой командой sed, мы сначала выкидываем мусор до и после этого «», а затем заменяем его на часть между «» и окружаем ее с помощью «& lt;».

0
ответ дан amo-ej1 31 August 2018 в 21:54
поделиться

Давайте посмотрим два эффективных способа, которые касаются экранированных кавычек. Эти шаблоны не предназначены для краткости и эстетики, но для эффективности.

Эти способы используют первую распознавание символов для быстрого поиска котировок в строке без затрат на чередование. (Идея состоит в том, чтобы быстро отбросить символы, которые не являются кавычками, без проверки двух ветвей чередования.)

Содержимое между кавычками описывается с развернутым контуром (вместо повторное чередование): [^"\\]*(?:\\.[^"\\]*)*

Очевидно, чтобы иметь дело со строками, которые не имеют сбалансированных кавычек, вместо этого вы можете использовать собственные квантификаторы: [^"\\]*+(?:\\.[^"\\]*)*+ или обходной путь для имитации их, чтобы предотвратить слишком много назад. Вы также можете выбрать, что цитируемая часть может быть открывающей цитатой до следующей (неэкспертированной) цитаты или конца строки. В этом случае нет необходимости использовать притяжательные квантификаторы, вам нужно только сделать последнее предложение необязательным.

Обратите внимание: иногда кавычки не экранируются с обратной косой чертой, а повторяя цитату. В этом случае подшаблон содержимого выглядит следующим образом: [^"]*(?:""[^"]*)*

Образцы избегают использования группы захвата и обратной ссылки (я имею в виду что-то вроде (["']).....\1) и используйте простое чередование, но с ["'] в начале, в коэффициенте.

Perl like:

["'](?:(?<=")[^"\\]*(?s:\\.[^"\\]*)*"|(?<=')[^'\\]*(?s:\\.[^'\\]*)*')

(обратите внимание, что (?s:...) является синтаксическим сахаром для переключения в режиме «dotall / singleline» внутри группы, не содержащей захвата. Если этот синтаксис не поддерживается, вы можете легко включить этот режим для всего шаблона или заменить точку на [\s\S])

(Способ написания этого шаблона полностью «ручным» и не учитывает возможные внутренние оптимизации двигателя)

Сценарий ECMA:

(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')

POSIX extended:

"[^"\\]*(\\(.|\n)[^"\\]*)*"|'[^'\\]*(\\(.|\n)[^'\\]*)*'

или просто:

"([^"\\]|\\.|\\\n)*"|'([^'\\]|\\.|\\\n)*'
20
ответ дан Casimir et Hippolyte 31 August 2018 в 21:54
поделиться

Образец (["'])(?:(?=(\\?))\2.)*?\1 выше выполняет эту работу, но меня беспокоят ее выступления (это неплохо, но может быть лучше). Мина ниже ее на 20% быстрее.

Шаблон "(.*?)" просто неполный. Мой совет для всех, кто это читает, просто НЕ ИСПОЛЬЗУЙТЕ ЭТО !!!

Например, он не может захватить много строк (при необходимости я могу предоставить исчерпывающий тестовый сценарий), как показано ниже:

$ string = 'Как вы? I \' m fine, thank you ';

Остальные из них так же хороши, как и выше.

Если вам действительно нравятся производительность и точность затем начинаются с одного ниже:

/(['"])((\\\1|.)*?)\1/gm

В моих тестах он охватывал каждую строку, которую я встречал, но если вы найдете что-то, что не работает, я бы с радостью обновил это для вас.

Проверьте мой шаблон в онлайн-тесте регулярного выражения .

5
ответ дан Eugen Mihailescu 31 August 2018 в 21:54
поделиться

Я работал над этим:

|([\'"])(.*?)\1|i

Я использовал в таком предложении:

preg_match_all('|([\'"])(.*?)\1|i', $cont, $matches);

, и он отлично работал.

3
ответ дан HamZa 31 August 2018 в 21:54
поделиться

Как ни странно, ни один из этих ответов не создает регулярное выражение, где возвращаемое совпадение является текстом внутри кавычек, что и требуется. MA-Madden пытается, но получает только внутренний матч как захваченную группу, а не весь матч. Один из способов сделать это:

(?<=(["']\b))(?:(?=(\\?))\2.)*?(?=\1)

Примеры для этого можно увидеть в этом демо https://regex101.com/r/Hbj8aP/1

Ключевым моментом здесь является положительный lookbehind в начале (?<=) и положительный результат в конце (?=). Lookbehind смотрит за текущим персонажем, чтобы проверить цитату, если она будет найдена, тогда начните оттуда, а затем lookahead проверит символ впереди для цитаты и, если будет найден, остановится на этом символе. Группа lookbehind (["']) заключена в скобки, чтобы создать группу для какой-либо цитаты, найденной в начале, затем она используется в конце lookahead (?=\1), чтобы убедиться, что она останавливается только тогда, когда находит соответствующую цитату.

Единственное другое осложнение состоит в том, что, поскольку lookahead на самом деле не потребляет конечную цитату, он будет снова найден с помощью начального lookbehind, который вызывает соответствие текста между конечными и стартовыми кавычками в одной и той же строке. Помещение границы слова на открытии цитаты (["']\b) помогает с этим, хотя в идеале я бы хотел пройти мимо взгляда, но я не думаю, что это возможно. Бит, позволяющий экранированным символам посередине, я взял непосредственно из ответа Адама.

7
ответ дан IrishDubGuy 31 August 2018 в 21:54
поделиться

БОЛЬШЕ ОТВЕТОВ! Вот решение, которое я использовал

\"([^\"]*?icon[^\"]*?)\"

TLDR; замените значок слова тем, что вы ищете в указанных цитатах и ​​voila!


Как это работает, он ищет ключевое слово и не заботится о том, что еще между кавычками. EG: id="fb-icon" id="icon-close" id="large-icon-close" регулярное выражение ищет метку кавычки ", тогда оно ищет любую возможную группу букв, которая не ", пока не найдет icon и любую возможную группу букв, которая не является ", тогда он ищет закрытие "

2
ответ дан James Harrington 31 August 2018 в 21:54
поделиться

В отличие от ответа Адама, у меня есть простой, но сработавший:

(["'])(?:\\\1|.)*?\1

И просто добавьте скобки, если вы хотите получить контент в кавычках следующим образом:

(["'])((?:\\\1|.)*?)\1

Затем $1 соответствует quote char и $2 соответствует строке содержимого.

0
ответ дан lon 31 August 2018 в 21:54
поделиться

RegEx принятого ответа возвращает значения, в том числе их кавычки: "Foo Bar" и "Another Value" в качестве совпадений.

Здесь находятся RegEx, которые возвращают только значения между кавычки (как задавал вопрошающий):

Только двойные кавычки (используйте значение группы захвата # 1):

"(.*?[^\\])"

Одиночные кавычки (использование значения группы захвата # 1):

'(.*?[^\\])'

Оба (использование значения группы захвата # 2):

(["'])(.*?[^\\])\1

-

Все поддерживаемые экранированные и вложенные кавычки.

5
ответ дан MA-Maddin 31 August 2018 в 21:54
поделиться

Я бы хотел:

"([^"]*)"

[^ "] является регулярным выражением для любого символа, кроме '" . Причина, по которой я использую это над не жадным многими операторами, так это то, что я должен продолжать искать это, чтобы убедиться, что я правильно понял.

71
ответ дан Martin York 31 August 2018 в 21:54
поделиться

От Greg H. Я смог создать это регулярное выражение в соответствии с моими потребностями.

Мне нужно было сопоставить определенное значение, которое было квалифицировано, находясь внутри кавычек. Это должно быть полное совпадение, никакое частичное совпадение не должно приводить к удару

, например. «test» не может соответствовать «test2».

reg = r"""(['"])(%s)\1"""
if re.search(reg%(needle), haystack, re.IGNORECASE):
    print "winning..."

Hunter

1
ответ дан motoprog 31 August 2018 в 21:54
поделиться

Если вы пытаетесь найти строки, которые имеют только определенный суффикс, например синтаксис точек, вы можете попробовать следующее:

\"([^\"]*?[^\"]*?)\".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".

0
ответ дан OffensivelyBad 31 August 2018 в 21:54
поделиться

В общем, следующий фрагмент регулярного выражения - это то, что вы ищете:

"(.*?)"

Используется не-жадный *? оператора, чтобы захватить все до, но не включая следующую двойную кавычку. Затем вы используете механизм, специфичный для языка, для извлечения совпадающего текста.

В Python вы можете сделать:

>>> import re
>>> string = '"Foo Bar" "Another Value"'
>>> print re.findall(r'"(.*?)"', string)
['Foo Bar', 'Another Value']
239
ответ дан Rodrigo Deodoro 31 August 2018 в 21:54
поделиться

Дополнительный ответ для подмножества кодеров 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
0
ответ дан S Meaden 31 August 2018 в 21:54
поделиться

Очень поздний ответ, но хотелось бы ответить

(\"[\w\s]+\")

http://regex101.com/r/cB0kB8/1

9
ответ дан Suganthan Madhavan Pillai 31 August 2018 в 21:54
поделиться

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

(['"])(?:(?!\1|\\).|\\.)*\1

Он делает трюк и все еще довольно прост и удобен в обслуживании.

Демо (с некоторыми более тестовыми примерами, не стесняйтесь использовать его и расширять).


PS: Если вам просто нужен контент между кавычки в полном совпадении ($0) и не боятся штрафа за производительность, используйте:

(?<=(['"])\b)(?:(?!\1|\\).|\\.)*(?=\1)

PPS: Если ваша фокусировка зависит исключительно от эффективности, перейдите к Решение Казимира и Ипполита ; это хороший.

1
ответ дан wp78de 31 August 2018 в 21:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: