Regex для замены всего \n в Строке, но не \n в [коде] [/кодом] тег

У меня есть причина. Может быть, вы дважды регистрируете Identity в своем приложении следующим образом:

Один из методов ConfigureServices класса запуска:

services.AddDefaultIdentity<IdentityUser>()
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<ApplicationDbContext>();

И другой в IdentityHostingStartup: [ 1110]

services.AddDefaultIdentity<IdentityUser>(config =>
                {
                    config.SignIn.RequireConfirmedEmail = true;
                }).AddEntityFrameworkStores<ApplicationDbContext>();

Зарегистрируйте Identity только в одном месте, т.е. либо в методе ConfigureServices, либо в IdentityHostingStartup.

Надеюсь, это поможет вам.

9
задан Matías 30 November 2008 в 03:22
поделиться

6 ответов

Я предложил бы (простой) синтаксический анализатор и не регулярное выражение. Что-то вроде этого (плохой псевдокод):

stack elementStack;

foreach(char in string) {
    if(string-from-char == "[code]") {
        elementStack.push("code");
        string-from-char = "";
    }

    if(string-from-char == "[/code]") {
        elementStack.popTo("code");
        string-from-char = "";
    }

    if(char == "\n" && !elementStack.contains("code")) {
        char = "<br/>\n";
    }
}
7
ответ дан 4 December 2019 в 10:34
поделиться

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

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

Ваш лексический анализатор определил бы пять маркеров: (" [код]", '\n', "[/код]", EOF: все другие строки:) и Ваш конечный автомат похож:

state    token    action
------------------------
begin    :none:   --> out
out      [code]   OUTPUT(token), --> in
out      \n       OUTPUT(break), OUTPUT(token)
out      *        OUTPUT(token)
in       [/code]  OUTPUT(token), --> out
in       *        OUTPUT(token)
*        EOF      --> end

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

Править: Лесоруб отмечает, что этот дизайн исключает использование" [/код]" в коде. Механизм Escape может использоваться для избиения этого. Чему-то нравится, добавьте '\' к своим маркерам и добавьте:

state    token    action
------------------------
in       \        -->esc-in
esc-in   *        OUTPUT(token), -->in
out      \        -->esc-out
esc-out  *        OUTPUT(token), -->out

к конечному автомату.

Обычные аргументы в пользу машины генерировали лексические анализаторы, и синтаксические анализаторы применяются.

6
ответ дан 4 December 2019 в 10:34
поделиться

Это, кажется, делает это:

private final static String PATTERN = "\\*+";

public static void main(String args[]) {
    Pattern p = Pattern.compile("(.*?)(\\[/?code\\])", Pattern.DOTALL);
    String s = "test 1 ** [code]test 2**blah[/code] test3 ** blah [code] test * 4 [code] test 5 * [/code] * test 6[/code] asdf **";
    Matcher m = p.matcher(s);
    StringBuffer sb = new StringBuffer(); // note: it has to be a StringBuffer not a StringBuilder because of the Pattern API
    int codeDepth = 0;
    while (m.find()) {
        if (codeDepth == 0) {
            m.appendReplacement(sb, m.group(1).replaceAll(PATTERN, ""));
        } else {
            m.appendReplacement(sb, m.group(1));
        }
        if (m.group(2).equals("[code]")) {
            codeDepth++;
        } else {
            codeDepth--;
        }
        sb.append(m.group(2));
    }
    if (codeDepth == 0) {
        StringBuffer sb2 = new StringBuffer();
        m.appendTail(sb2);
        sb.append(sb2.toString().replaceAll(PATTERN, ""));
    } else {
        m.appendTail(sb);
    }
    System.out.printf("Original: %s%n", s);
    System.out.printf("Processed: %s%n", sb);
}

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

3
ответ дан 4 December 2019 в 10:34
поделиться

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

После поиска я нашел что-то завершением решения cletus, кроме я предположил, что блок кода не может быть вложен, ведя к более простому коду: выберите то, что подходит для Ваших потребностей.

import java.util.regex.*;

class Test
{
  static final String testString = "foo\nbar\n[code]\nprint'';\nprint{'c'};\n[/code]\nbar\nfoo";
  static final String replaceString = "<br>\n";
  public static void main(String args[])
  {
    Pattern p = Pattern.compile("(.+?)(\\[code\\].*?\\[/code\\])?", Pattern.DOTALL);
    Matcher m = p.matcher(testString);
    StringBuilder result = new StringBuilder();
    while (m.find()) 
    {
      result.append(m.group(1).replaceAll("\\n", replaceString));
      if (m.group(2) != null)
      {
        result.append(m.group(2));
      }
    }
    System.out.println(result.toString());
  }
}

Сырой быстрый тест, Вам нужно больше (пустой указатель, пустая строка, никакой тег кода, несколько, и т.д.).

1
ответ дан 4 December 2019 в 10:34
поделиться

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

(\[code\].*\[/code\])

Затем выражение будет соответствовать всему сначала [code] отметьте к последнему [/code] тег, который является ясно не, что Вы хотите. В то время как существуют способы обойти это, получающиеся регулярные выражения являются обычно хрупкими, неинтуитивными, и совершенно ужасными. Что-то как следующий код Python работало бы намного лучше.

output = []
def add_brs(str):
    return str.replace('\n','<br/>\n')
# the first block will *not* have a matching [/code] tag
blocks = input.split('[code]')
output.push(add_brs(blocks[0]))
# for all the rest of the blocks, only add <br/> tags to
# the segment after the [/code] segment
for block in blocks[1:]:
    if len(block.split('[/code]'))!=1:
        raise ParseException('Too many or few [/code] tags')
    else:
        # the segment in the code block is pre, everything
        # after is post
        pre, post = block.split('[/code]')
        output.push(pre)
        output.push(add_brs(post))
# finally join all the processed segments together
output = "".join(output)

Обратите внимание, что вышеупомянутый код не был протестирован, это - просто общее представление о том, что необходимо будет сделать.

2
ответ дан 4 December 2019 в 10:34
поделиться

Для разбираний в нем действительно необходимо сделать три передачи:

  1. Найдите [кодируют] блоки и заменяют их уникальным маркером + индекс (сохраняющий исходный блок), например, "нечто [код] abc [/код] панель [код] efg [/код]" становится "МАРКЕРОМ нечто 1 barTOKEN-2"
  2. Сделайте свою замену новой строки.
  3. Сканирование для маркеров Escape и восстановления исходный блок.

Код смотрит что-то* как:

Matcher m = escapePattern.matcher(input);
while(m.find()) {
    String key = nextKey();
    escaped.put(key,m.group());
    m.appendReplacement(output1,"TOKEN-"+key);
}
m.appendTail(output1);
Matcher m2 = newlinePatten.matcher(output1);
while(m2.find()) {
    m.appendReplacement(output2,newlineReplacement);
}
m2.appendTail(output2);
Matcher m3 = Pattern.compile("TOKEN-(\\d+)").matcher(output2); 
while(m3.find()) {
    m.appendReplacement(finalOutput,escaped.get(m3.group(1)));
}
m.appendTail(finalOutput);

Это - быстрый и грязный путь. Существуют более эффективные пути (другие упомянули синтаксический анализатор/лексические анализаторы), но если Вы не обрабатываете миллионы строк, и Ваш код является зависящим от ЦП (а не связанный ввод-вывод, как большинство веб-приложений), и Вы подтвердили с профилировщиком, что это - узкое место, они, вероятно, не стоят того.

* я не выполнил его, это - все из памяти. Просто проверьте API, и Вы сможете разработать его.

1
ответ дан 4 December 2019 в 10:34
поделиться
Другие вопросы по тегам:

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