Regex для разделения строкового пространства использующего при отсутствии окружения одинарными или двойными кавычками

Ошибка синтаксиса: ошибка синтаксиса, неожиданный T_ENCAPSED_AND_WHITESPACE

Эта ошибка чаще всего встречается при попытке ссылаться на значение массива с помощью ключевого слова для интерполяции внутри строки с двумя кавычками , когда вся конструкция комплексной переменной не заключена в {}.

Случай ошибки:

Это приведет к Unexpected T_ENCAPSED_AND_WHITESPACE:

echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^

Возможные исправления:

В строке с двойными кавычками PHP разрешает использовать строки ключей ключей без кавычек и не выдаст E_NOTICE. Таким образом, вышесказанное может быть записано как:

echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^

Вся сложная переменная массива и ключ (ы) могут быть заключены в {}, и в этом случае они должны быть указаны чтобы избежать E_NOTICE. Документация PHP рекомендует этот синтаксис для сложных переменных.

echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";

Конечно, альтернатива любой из вышеперечисленного заключается в объединении переменной массива in вместо интерполировать его:

echo "This is a double-quoted string with an array variable " . $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^

Для справки см. раздел «Переменная синтаксический анализ» в странице руководства PHP Strings

107
задан Jason Plank 3 August 2011 в 19:05
поделиться

6 ответов

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

[^\s"']+|"([^"]*)"|'([^']*)'

я добавил группы фиксации, потому что Вы не хотите кавычки в списке.

Этот код Java создает список, добавляя группу фиксации, если это соответствовало для исключения кавычек и добавления полного соответствия regex, если группа фиксации не соответствовала (неупомянутое слово было распознано).

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
    if (regexMatcher.group(1) != null) {
        // Add double-quoted string without the quotes
        matchList.add(regexMatcher.group(1));
    } else if (regexMatcher.group(2) != null) {
        // Add single-quoted string without the quotes
        matchList.add(regexMatcher.group(2));
    } else {
        // Add unquoted word
        matchList.add(regexMatcher.group());
    }
} 

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

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
    matchList.add(regexMatcher.group());
} 
232
ответ дан Alan Moore 24 November 2019 в 03:38
поделиться

Существует несколько вопросов на StackOverflow, которые покрывают этот тот же вопрос в различных контекстах с помощью регулярных выражений. Например:

ОБНОВЛЕНИЕ : Образец regex для обработки единственных и двойных заключенных в кавычки строк. Касательно: , Как я могу разделить на строке кроме тех случаев, когда в заключает в кавычки?

m/('.*?'|".*?"|\S+)/g 

Протестированный это с быстрым отрывком Perl и выводом было как воспроизведено ниже. Также работы для пустых строк или строк только для пробела, если они между кавычками (не уверенный, если это желаемо или не).

This
is
a
string
that
"will be"
highlighted
when
your
'regular expression'
matches
something.

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

13
ответ дан Community 24 November 2019 в 03:38
поделиться

Если Вы хотите позволить оставленные кавычки в строке, можно использовать что-то вроде этого:

(?:(['"])(.*?)(?<!\\)(?>\\\\)*\1|([^\s]+))

Заключенные в кавычки строки будут группой 2, единственные неупомянутые слова будут группой 3.

, можно попробовать его на различных строках здесь: http://www.fileformat.info/tool/regex.htm или http://gskinner.com/RegExr/

5
ответ дан mcrumley 24 November 2019 в 03:38
поделиться

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

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

(не фактический Java)

string = "This is a string that \"will be\" highlighted when your 'regular expression' matches something.";

regex = "\"(\\\"|(?!\\\").)+\"|[^ ]+"; // search for a quoted or non-spaced group
final = new Array();

while (string.length > 0) {
    string = string.trim();
    if (Regex(regex).test(string)) {
        final.push(Regex(regex).match(string)[0]);
        string = string.replace(regex, ""); // progress to next "word"
    }
}
<час>

кроме того, получая одинарные кавычки мог привести к проблемам:

"Foo's Bar 'n Grill"

//=>

"Foo"
"s Bar "
"n"
"Grill"
1
ответ дан Jonathan Lonowski 24 November 2019 в 03:38
поделиться

String.split() не полезно здесь, потому что нет никакого способа различать пробелы в кавычках (не разделяйте), и те вне (разделения). Matcher.lookingAt(), вероятно, в чем Вы нуждаетесь:

String str = "This is a string that \"will be\" highlighted when your 'regular expression' matches something.";
str = str + " "; // add trailing space
int len = str.length();
Matcher m = Pattern.compile("((\"[^\"]+?\")|('[^']+?')|([^\\s]+?))\\s++").matcher(str);

for (int i = 0; i < len; i++)
{
    m.region(i, len);

    if (m.lookingAt())
    {
        String s = m.group(1);

        if ((s.startsWith("\"") && s.endsWith("\"")) ||
            (s.startsWith("'") && s.endsWith("'")))
        {
            s = s.substring(1, s.length() - 1);
        }

        System.out.println(i + ": \"" + s + "\"");
        i += (m.group(0).length() - 1);
    }
}

, который производит следующий вывод:

0: "This"
5: "is"
8: "a"
10: "string"
17: "that"
22: "will be"
32: "highlighted"
44: "when"
49: "your"
54: "regular expression"
75: "matches"
83: "something."
1
ответ дан Zach Scrivena 24 November 2019 в 03:38
поделиться

Я довольно уверен, что это не одни только возможные регулярные выражения использования. Проверка, содержится ли что-то в некотором другом теге, является операцией парсинга. Это походит на ту же проблему как пытающийся проанализировать XML с regex - это не может быть сделано правильно. Можно быть в состоянии получить желаемый результат путем повторного применения нежадного, неглобального regex, который соответствует заключенным в кавычки строкам, тогда как только Вы не можете найти ничто больше, разделить его в пробелах..., который имеет много проблем, включая отслеживание первоначального заказа всех подстрок. Ваш лучший выбор состоит в том, чтобы просто записать действительно простую функцию, которая выполняет итерации по строке и вытаскивает маркеры, которые Вы хотите.

0
ответ дан rmeador 24 November 2019 в 03:38
поделиться
Другие вопросы по тегам:

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