183

スペースで区切られた数値と一致させるために正規表現を使用しようとしています。\b(「単語の境界」)の正確な定義が見つかりません。私はそれ-12が「整数の単語」(と一致する \b\-?\d+\b)であると想定していましたが、これは機能しないようです。の方法を知っていただければ幸いです。

[Java1.6でJava正規表現を使用しています]

例:

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());

これは次を返します:

true
false
true
4

13 に答える 13

140

\w単語の境界は、ほとんどの正規表現の方言で、と(単語以外の文字)の間の位置\W、または文字列が単語文字()で始まるか終わる場合は文字列の最初または最後にあります[0-9A-Za-z_]

したがって、文字列"-12"では、1の前または2の後に一致します。ダッシュは単語文字ではありません。

于 2009-08-24T21:00:23.717 に答える
50

正規表現を学ぶ過程で、私は本当にメタ文字であるに固執しました\b「それが何なのか、それが何なのか」を繰り返し自問している間、私は確かにその意味を理解していませんでした。ウェブサイトを使って何度か試した後、単語の最初と最後にあるピンク色の縦のダッシュに気をつけました。当時はその意味がよくわかりました。これで、正確にword(\w)-boundaryになりました。

私の見解は、単に非常に理解を重視することです。その背後にある論理は、別の回答から検討する必要があります。

ここに画像の説明を入力してください

于 2018-06-01T01:19:26.427 に答える
33

単語の境界は、次の3つの位置のいずれかで発生する可能性があります。

  1. 文字列の最初の文字の前。最初の文字が単語文字の場合。
  2. 文字列の最後の文字の後、最後の文字が単語文字の場合。
  3. 文字列内の2つの文字の間。一方は単語文字で、もう一方は単語文字ではありません。

単語の文字は英数字です。マイナス記号はそうではありません。正規表現チュートリアルから取得。

于 2009-08-24T21:05:57.323 に答える
20

アラン・ムーアの答えを説明したいと思います

単語の境界とは、単語の文字が前にあり、その後に1つがないか、単語の文字が後にあり、前に1がない位置です。

「これはcatであり、彼女は素晴らしい」という文字列があり、この文字(「 a 」)が「単語の境界」に存在する場合にのみ、文字「 a 」のすべての出現箇所を置き換えたいとします。 、

言い換えると、 「cat」内の文字は置き換えないでください。a

だから私は(Pythonで)正規表現を次のように実行します

re.sub(r"\ba","e", myString.strip())//に置き換えaますe

したがって、出力は次のようになります

これはcatあり、彼女素晴らしいです->

これは彼女素晴らしいです//結果

于 2019-02-11T11:39:19.393 に答える
16

単語の境界とは、単語の文字が前にあり、その後にない位置、または単語の文字が後にあり、前に1がない位置のことです。

于 2009-08-25T01:36:03.480 に答える
10

ここで\bは、実際にどのようなスタイルの正規表現境界があるかについて説明します。

短編小説は、それらが条件付きであるということです。彼らの行動は彼らが隣にいるものに依存します。

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

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

時々それはあなたが望むものではありません。詳細については、他の回答を参照してください。

于 2010-11-18T13:35:46.277 に答える
7

.NET、、、、などの単語をテキストで検索すると、さらに悪い問題が発生しましC++た。コンピュータープログラマーは、正規表現を書くのが難しい言語に名前を付けるよりもよく知っていると思うでしょう。C#C

とにかく、これは私が見つけたものです(主にhttp://www.regular-expressions.infoから要約されています。これは素晴らしいサイトです):正規表現のほとんどのフレーバーでは、短縮文字クラスと一致する文字\wは単語の境界によって単語文字として扱われる文字。Javaは例外です。JavaはUnicodeをサポートしていますが、はサポートして\bいません\w。(当時、それには正当な理由があったと確信しています)。

「単語文字」の\w略です。常にASCII文字と一致し[A-Za-z0-9_]ます。アンダースコアと数字が含まれていることに注意してください(ただし、ダッシュは含まれていません)。Unicodeをサポートするほとんどのフレーバーに\wは、他のスクリプトの多くの文字が含まれています。どのキャラクターが実際に含まれるかについては、多くの矛盾があります。アルファベットの文字や表意文字からの文字や数字が一般的に含まれています。数字ではないアンダースコアおよび数字記号以外のコネクタ句読点は、含まれる場合と含まれない場合があります。XMLスキーマとXPathには、すべてのシンボルが含まれてい\wます。ただし、Java、JavaScript、およびPCREは、ASCII文字とのみ一致し\wます。

C++これが、Javaベースの正規表現が、、C#または.NET(ピリオドとプラスをエスケープすることを覚えている場合でも)を検索する理由です\b

注:文末のピリオドの後に誰かがスペースを入れなかった場合など、テキストの間違いをどうすればよいかわかりません。私はそれを許可しましたが、それが必ずしも正しいことであるかどうかはわかりません。

とにかく、Javaでは、これらの奇妙な名前の言語のテキストを検索する場合は、\b空白と句読点の指定子の前後をに置き換える必要があります。例えば:

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();
}

次に、テストまたはメイン機能で:

    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));

PS http://regexpal.com/に感謝します。これがないと、正規表現の世界は非常に悲惨なものになります。

于 2013-12-16T16:54:42.033 に答える
4

境界条件に関するドキュメントを確認してください。

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

このサンプルをチェックしてください:

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")));
    }

印刷するときは、出力が次のようになっていることに注意してください。

[文字列に値-が見つかりました。]

これは、「-」文字が単語文字とは見なされないため、単語の境界にあるものとして検出されないことを意味します。@brianaryがちょっと私を打ち負かしたように見えるので、彼は賛成票を獲得します。

于 2009-08-24T21:03:56.033 に答える
3

参照:正規表現の習得(Jeffrey EF Friedl)-O'Reilly

\bはと同等です(?<!\w)(?=\w)|(?<=\w)(?!\w)

于 2020-10-17T15:28:00.090 に答える
2

単語境界\bは、1つの単語が単語文字で、別の単語が非単語文字である場合に使用されます。負の数の正規表現は

--?\b\d+\b

動作中のデモを確認してください

于 2018-11-08T10:38:59.707 に答える
1

あなたの問題は-、単語の文字ではないという事実によるものだと思います。したがって、単語の境界は、の後に一致する-ため、それをキャプチャしません。単語の境界は、文字列の最初と最後の単語文字の前、および単語文字または非単語文字の前とその反対の場所で一致します。また、単語の境界は幅がゼロの一致であることに注意してください。

考えられる代替案の1つは

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

これは、スペース文字とオプションのダッシュで始まり、単語の境界で終わるすべての数字と一致します。また、文字列の先頭から始まる番号と一致します。

于 2009-08-24T20:59:46.557 に答える
0

これを使用する\\b(\\w+)+\\bと、単語文字のみを含む単語と完全に一致することを意味します([a-zA-Z0-9])

たとえば\\b、正規表現の先頭に設定すると(スペース付きで)受け入れられますが、 (スペースなしで)-12受け入れられません。-12

私の言葉をサポートするための参照:https ://docs.oracle.com/javase/tutorial/essential/regex/bounds.html

于 2017-11-19T16:41:37.860 に答える
-1

これは、最後の一致または文字列の最初または最後の境界(つまり、文字の後に続く)だと思います。

于 2009-08-24T20:55:23.930 に答える