регулярное выражение для соответствия простой уценке - PullRequest
5 голосов
/ 28 мая 2019

Я пытаюсь определить регулярное выражение, чтобы оно соответствовало всем случаям *this kind of strings*.Два дополнительных правила, к сожалению, сделали эту вещь более сложной, чем я думал:

  1. помеченная строка должна начинаться с *, за которым следует непробельный символ (поэтому * this one* не должен совпадать
  2. помеченная строка должна заканчиваться непустым пробелом, за которым следует *, за которым следует пробел (поэтому *this one * и *this o*ne не должны совпадать

Я начал с простейшего регулярного выражения \*\S([^\*]+)?\*, которое для моегострока тестирования:

*foo 1 * 2 bar* foo *b* azz *qu **ux*

соответствует местам в квадратных скобках:

[*foo 1 *] 2 bar* foo [*b*] azz [*qu *][*ux*]

, и это то, чего я хотел бы достичь:

[*foo 1 * 2 bar*] foo [*b*] azz [*qu **ux*]

, поэтому появляются 2 проблемы:

  • как выразить в регулярном выражении правило от 2. "поиск до первого непробельного символа, следующего за * с пробелом появляется «положительный взгляд»
  • как сопоставить пробел из правила 2. но не включить его в результат, что \*\S([^\*]+)?\*\s будет делать?

Ответы [ 4 ]

2 голосов
/ 28 мая 2019

Если вы хотите начать сопоставление с крайнего справа *, вы можете использовать

\*(?=[^\s*]).*?(?<=[^\s*])\*(?!\S)

Чтобы начать сопоставление с самого левого * (как в ``), удалите * из первого обхода (или замените его шаблон на \S):

\*(?=\S).*?(?<=[^\s*])\*(?!\S)

См. демонстрацию regex # 1 и демонстрацию regex# 2 .Добавьте (?s) в начале или скомпилируйте с помощью Pattern.DOTALL, чтобы сопоставить тексты между строками.

Подробности

  • \* - * char
  • (?=[^\s*]) - следующий символ должен быть не пробелом, а не *
  • .*? - любой 0+ символ как можно меньше
  • (?<=[^\s*]) - предыдущий символ должен быть не пробелом, а не *
  • \* - * char
  • (?!\S) - образец границы пробела, следующийchar может быть пробелом, или конец строки может находиться в этом месте строки.

В Java:

String regex = "\\*(?=[^\\s*]).*?(?<=[^\\s*])\\*(?!\\S)";
1 голос
/ 28 мая 2019

Вы можете использовать это регулярное выражение:

\*(?!\s)(.*?)(?<!\s|\*)\*(?=\s|$)

как выразить в регулярном выражении правило от 2. "поиск до первого непробельного символа, сопровождаемого * последующим пробельным символом"? позитивный взгляд?

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

как сопоставить пробел из правила 2. но не включить его в результат, который * \ S ([^ *] +)? * \ S сделает?

Если вы хотите проверить, сопровождается ли символ pattern символом, не потребляя его, вы можете использовать прогноз, например, pattern(?=\s) не будет потреблять \s в отличие от pattern\s.

0 голосов
/ 28 мая 2019
public class Test {

    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("\\*\\S.*?(?<!\\s)\\*(?=\\s|$)");
        Matcher matcher = pattern.matcher("*foo 1 * 2 bar* foo *b* azz *qu **ux*");
        int i = 1;
        while(matcher.find()) {
            System.out.printf("%d: %s%n", i++, matcher.group());
        }
    }
}

* \ S : * с последующим непробельным символом

. *? : потреблять символы без жадности.

(?

0 голосов
/ 28 мая 2019

Я использовал полные совпадения, а не группы, и он идеально соответствовал вашей тестовой строке:

"(?<=\\s|^)\\*(?:\\S|\\S.*?\\S)\\*(?=\\s)"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...