2008 SQLServer теперь имеет тип данных 'даты', который содержит только дату без компонента времени. Любой использующий SQLServer 2008 и вне может сделать следующее:
SELECT CONVERT(date, GETDATE())
Это правда, что регулярные выражения не могут считаться, но они можно использовать , чтобы определить, есть ли что-то четное или нечетное. Уловка в этом случае состоит в том, чтобы исследовать кавычки после трубы, а не перед ней.
str = str.replace(/\|(?=(?:(?:[^"]*"){2})*[^"]*$)/g, "OR");
Разбивая это на части, (?: [^ "] *") {2}
соответствует следующей паре кавычек, если она есть, вместе с промежуточными кавычками. После того, как вы проделаете это столько раз, сколько сможете (что может быть равно нулю), [^ " ] * $
использует все оставшиеся не заключенные в кавычки до конца строки.
Конечно, это предполагает, что текст имеет правильный формат. Он также не решает проблему экранированных кавычек, но может, если вам это нужно.
Регулярные выражения не учитываются. Для этого нужны парсеры.
Вы можете найти Perl FAQ по этому вопросу актуально.
#!/usr/bin/perl
use strict;
use warnings;
my $x = qq{"this | that" | "the | other"};
print join('" OR "', split /" \| "/, $x), "\n";
Возможно, вы ищете что-то вроде этого:
(?<=^([^"]*"[^"]*")+[^"|]*)\|
Всем спасибо. Приносим извинения за то, что не упомянули, что это в javascript, и что термины не нужно цитировать, и может быть любое количество цитируемых / некотируемых терминов, например:
"this | that" | "the | other" | yet | another -> "this | that" OR "the | other" OR yet OR another
Дэниел, кажется, что это примерно, то есть в основном соответствие / массажная петля. Спасибо за подробное объяснение. В js это выглядит как разбиение, цикл forEach для массива терминов, отправка термина (после изменения | термина на OR) обратно в массив и повторное соединение.
Вам не нужно считать, потому что вы не вкладываете кавычки. Это будет делать:
#!/usr/bin/perl
my $str = '" this \" | that" | "the | other" | "still | something | else"';
print "$str\n";
while($str =~ /^((?:[^"|\\]*|\\.|"(?:[^\\"]|\\.)*")*)\|/) {
$str =~ s/^((?:[^"|\\]*|\\.|"(?:[^\\"]|\\.)*")*)\|/$1OR/;
}
print "$str\n";
Теперь давайте объясним это выражение.
^ -- means you'll always match everything from the beginning of the string, otherwise
the match might start inside a quote, and break everything
(...)\| -- this means you'll match a certain pattern, followed by a |, which appears
escaped here; so when you replace it with $1OR, you keep everything, but
replace the |.
(?:...)* -- This is a non-matching group, which can be repeated multiple times; we
use a group here so we can repeat multiple times alternative patterns.
[^"|\\]* -- This is the first pattern. Anything that isn't a pipe, an escape character
or a quote.
\\. -- This is the second pattern. Basically, an escape character and anything
that follows it.
"(?:...)*" -- This is the third pattern. Open quote, followed by a another
non-matching group repeated multiple times, followed by a closing
quote.
[^\\"] -- This is the first pattern in the second non-matching group. It's anything
except an escape character or a quote.
\\. -- This is the second pattern in the second non-matching group. It's an
escape character and whatever follows it.
Результат будет следующим:
" this \" | that" | "the | other" | "still | something | else"
" this \" | that" OR "the | other" OR "still | something | else"
Другой подход (похожий на рабочий ответ Алана М):
str = str.replace(/(".+?"|\w+)\s*\|\s*/g, '$1 OR ');
Часть внутри первой группы (с интервалом для удобочитаемости):
".+?" | \w+
... в основном означает, что-то процитированное или слово. Остаток означает, что за ним следует "|" заключен в необязательный пробел. Замена состоит в том, что первая часть («$ 1» означает первую группу), за которой следует «ИЛИ».
@Alan M, works nicely, escaping not necessary due to the sparseness of sqlite FTS capabilities.
@epost, accepted solution for brevity and elegance, thanks. it needed to merely be put in a more general form for unicode etc.
(".+?"|[^\"\s]+)\s*\|\s*