FJは原因について正しいです。
行で始まる最初のword-charシーケンスを明示的に一致a
させるには、単語以外の文字またはASCII文字以外の単語で始まる任意の数の単語を一致させa
、オプションのキャプチャされたa
単語の後に無視されたものを続けることができます。
abc
このプログラムは、期待どおりに印刷されます
import java.util.regex.*;
public class Foo {
public static void main(String[] argv) {
Pattern p = Pattern.compile("^(?:\\W|[b-zA-Z]\\w+)*(?:(a\\w*)?(?:.*))$");
Matcher m = p.matcher("xxx abc yyy");
if (m.matches()) System.out.println(m.group(1));
}
}
正規表現は明確であるため、文字列に対して1回のフォワードパスのみが必要です。ただし、もっと注意深く読む必要があります。
私の傾向は、これらの状況は通常、明示的にトークン化することです-単語と非単語に分割してから、配列をループして必要なものを探します。
または、アンカーされていない正規表現のfind
代わりに使用することもできます。match
find()
パターンに一致する入力シーケンスの次のサブシーケンスを見つけようとします。
だからあなたはすることができます
Pattern p = Pattern.compile("(\\ba\\w*\\b)?");
Matcher m = p.matcher("xxx abc yyy")
while (m.find()) { System.out.println(m.group(1)); }
または、最初のものだけが必要な場合は、while
をに置き換えます。if
最後に、$
Javaでの入力の終了を意味するものではありません。これは、入力の終了、または入力の終了時の改行の直前を意味します。javadocは、エンドアンカー間の微妙な違いを説明しています。
$
行
\Z
の終わり入力の終わりですが、最後のターミネータ(存在する場合)の場合
\z
入力の終わり