Pergunta

Eu estou usando Java expressões regulares em Java 1.6 (inter alia para analisar saída numérico) e não consegue encontrar uma definição precisa de \b ( "limite de palavra"). Eu tinha assumido que -12 seria uma "palavra inteira" (acompanhado por \b\-?\d+\b), mas parece que isso não funciona. Eu ficaria grato por saber de formas de adequar os números separados por espaços.

Exemplo:

Pattern pattern = Pattern.compile("\\s*\\b\\-?\\d+\\s*");
String plus = " 12 ";
System.out.println(""+pattern.matcher(plus).matches());
String minus = " -12 ";
System.out.println(""+pattern.matcher(minus).matches());
pattern = Pattern.compile("\\s*\\-?\\d+\\s*");
System.out.println(""+pattern.matcher(minus).matches());

Este retornos:

true
false
true
Foi útil?

Solução

Um limite de palavra, na maioria dos dialetos regex, é uma posição entre \w e \W (char não palavra), ou no início ou no final de uma cadeia de se começar ou extremidades (respectivamente) com um caractere de palavra ([0-9A-Za-z_]) .

Assim, no "-12" string, ela iria corresponder antes da 1 ou após a 2. O traço não é um caractere de palavra.

Outras dicas

Um limite de palavra pode ocorrer em uma das três posições:

  1. Antes do primeiro caractere na seqüência, se o primeiro caractere é um caractere de palavra.
  2. Após o último caractere na seqüência, se o último caractere é um caractere de palavra.
  3. Entre dois caracteres na cadeia, onde um é um caractere de palavra e o outro não é um caractere de palavra.

caracteres do Word são alfa-numérico; um sinal de menos não é. Tomado de Regex Tutorial .

Um limite de palavra é uma posição que é ou precedido por um caractere de palavra e não seguido por um, ou seguido de um caractere de palavra e não precedida por um.

I falar sobre o que limites regex estilo \b realmente são aqui .

A história curta é que eles são condicional . Seu comportamento depende do que eles estão ao lado.

# same as using a \b before:
(?(?=\w) (?<!\w)  | (?<!\W) )

# same as using a \b after:
(?(?<=\w) (?!\w)  | (?!\W)  )

Às vezes isso não é o que você quer. Veja minha outra resposta para a elaboração.

Confira a documentação em condições de contorno:

http://java.sun.com/docs /books/tutorial/essential/regex/bounds.html

Confira este exemplo:

public static void main(final String[] args)
    {
        String x = "I found the value -12 in my string.";
        System.err.println(Arrays.toString(x.split("\\b-?\\d+\\b")));
    }

Quando você imprimi-lo, observe que a saída é o seguinte:

[I encontrado o valor -, na minha string.]

Isto significa que o caractere "-" não está sendo pego como sendo no limite de uma palavra porque não é considerado um caractere de palavra. Looks como @brianary bater-me um bocado para o soco, então ele recebe um up-voto.

Eu corri para um problema ainda pior quando procurar texto para palavras como .NET, C++, C# e C. Você poderia pensar que os programadores de computador que sabe melhor do que para citar algo linguagem que é difícil escrever expressões regulares para.

De qualquer forma, este é o que eu descobri (resumidas na maior parte do http://www.regular-expressions.info , que é um grande site): na maioria dos sabores de regex, personagens que são correspondidos pela \w classe de personagem de curto mão são os personagens que são tratados como caracteres de palavra por palavra fronteiras. Java é uma exceção. Java suporta Unicode para \b mas não para \w. (Estou certo de que havia uma boa razão para isso na época).

O \w significa "caráter palavra". Ele sempre corresponde ao [A-Za-z0-9_] caracteres ASCII. Observe a inclusão do sublinhado e dígitos (mas não traço!). Na maioria dos sabores que suportam Unicode, \w inclui muitos personagens de outros scripts. Há um monte de inconsistência sobre quais personagens são realmente incluídos. Letras e algarismos de escritas alfabéticas e ideogramas são geralmente incluídos. Conector de pontuação exceto o sublinhado e símbolos numéricos que não são podem ou não ser incluídos dígitos. XML Schema e XPath até mesmo incluir todos os símbolos em \w. Mas Java, JavaScript, e PCRE corresponder apenas caracteres ASCII com \w.

Qual é pesquisas regex porque baseadas em Java para C++, C# ou .NET (mesmo quando você se lembrar de escapar do período e vantagens) são parafusados ??pelo \b.

Nota: Eu não tenho certeza o que fazer sobre erros no texto, como quando alguém não colocar um espaço depois de um período no final de uma frase. Eu permiti-lo, mas não tenho certeza de que é necessariamente a coisa certa a fazer.

De qualquer forma, em Java, se você está à procura de texto para as essas línguas estranhas-nomeado, você precisará substituir o \b com antes e depois de espaço em branco e pontuação designadores. Por exemplo:

public static String grep(String regexp, String multiLineStringToSearch) {
    String result = "";
    String[] lines = multiLineStringToSearch.split("\\n");
    Pattern pattern = Pattern.compile(regexp);
    for (String line : lines) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            result = result + "\n" + line;
        }
    }
    return result.trim();
}

Então em seu teste ou função principal:

    String beforeWord = "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|^)";   
    String afterWord =  "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|$)";
    text = "Programming in C, (C++) C#, Java, and .NET.";
    System.out.println("text="+text);
    // Here is where Java word boundaries do not work correctly on "cutesy" computer language names.  
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for .NET="+ grep("\\b\\.NET\\b", text));
    System.out.println("Should find: grep exactly for .NET="+ grep(beforeWord+"\\.NET"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for C#="+ grep("\\bC#\\b", text));
    System.out.println("Should find: grep exactly for C#="+ grep("C#"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java:grep with word boundary for C++="+ grep("\\bC\\+\\+\\b", text));
    System.out.println("Should find: grep exactly for C++="+ grep(beforeWord+"C\\+\\+"+afterWord, text));

    System.out.println("Should find: grep with word boundary for Java="+ grep("\\bJava\\b", text));
    System.out.println("Should find: grep for case-insensitive java="+ grep("?i)\\bjava\\b", text));
    System.out.println("Should find: grep with word boundary for C="+ grep("\\bC\\b", text));  // Works Ok for this example, but see below
    // Because of the stupid too-short cutsey name, searches find stuff it shouldn't.
    text = "Worked on C&O (Chesapeake and Ohio) Canal when I was younger; more recently developed in Lisp.";
    System.out.println("text="+text);
    System.out.println("Bad word boundary because of C name: grep with word boundary for C="+ grep("\\bC\\b", text));
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
    // Make sure the first and last cases work OK.

    text = "C is a language that should have been named differently.";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    text = "One language that should have been named differently is C";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    //Make sure we don't get false positives
    text = "The letter 'c' can be hard as in Cat, or soft as in Cindy. Computer languages should not require disambiguation (e.g. Ruby, Python vs. Fortran, Hadoop)";
    System.out.println("text="+text);
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

P.S. Meus agradecimentos a http://regexpal.com/ sem os quais o mundo regex seria muito infeliz!

No curso de aprendizagem de expressão regular, eu estava realmente preso no metacharacter que é \b. Eu, na verdade não compreender o seu significado, enquanto eu estava me perguntando " o que é, o que é " repetidamente. Depois de algumas tentativas, usando o site , eu assisto os traços verticais rosa no todo começo de palavras e no final de palavras. Eu entendi o seu significado bem naquele momento. Agora é exatamente palavra (\w) -BOUNDARY .

Meu ponto de vista é simplesmente imensamente a compreensão orientada. Lógica por trás dela deve ser examinado a partir de mais respostas.

enter descrição da imagem aqui

Eu gostaria de explicar resposta Alan de Moore

Um limite de palavra é uma posição que é ou precedido por um caractere de palavra e não seguido por um, ou seguido de um caractere de palavra e não precedida por um.

Suponha que eu tenho um string "Este é a c a t e ela de a wesome", e eu deveria substituir todos ocorrência (s) a letra 'a' somente se esta carta existe no "Boundry de uma palavra" ou seja, a carta a dentro 'cat' não deve ser substituído.

Então, eu vou executar regex (em Python ) como

re.sub("\ba","e", myString.strip()) // substituir a com e

para saída será Esta é e c a t end ela é ewesome

Eu acredito que o problema é devido ao fato de que - não é um caractere de palavra. Assim, o limite de palavra irá corresponder após a -, e por isso não irá capturá-lo. limites de palavra corresponder antes da primeira e após os últimos caracteres de texto em uma corda, bem como em qualquer lugar onde antes que seja um personagem de caráter palavra ou não palavra, e depois que ele é o oposto. Observe também que limite de palavra é um jogo de largura zero.

Uma alternativa possível é

(?:(?:^|\s)-?)\d+\b

Isso irá corresponder a todos os números que começam com um caractere de espaço e um traço opcional, e terminando em um limite de palavra. Ele também irá corresponder a um número a partir do início da string.

limite de palavra \ b é usado onde uma palavra deve ser um caractere de palavra e outra um caractere não-palavra. Expressão regular para número negativo deve ser

--?\b\d+\b

DEMONSTRA

Eu acho que é o limite (ou seja caráter seguinte) da última partida ou no início ou no final da cadeia.

quando você usa \\b(\\w+)+\\b que isso significa exatamente coincidir com uma palavra contendo apenas caracteres de texto ([a-zA-Z0-9])

no seu caso, por exemplo, configuração \\b no início da regex aceitará -12 (com espaço), mas novamente não aceitará -12 (sem espaço)

para referência para apoiar as minhas palavras: https: // docs. oracle.com/javase/tutorial/essential/regex/bounds.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top