チキンなど、括弧で囲まれていないすべての単語を取得する正規表現を作成しようとしています。以下のようなので
chicken
選ばれますが、
[chicken]
しません。誰もこれを行う方法を知っていますか?
String template = "[chicken]";
String pattern = "\\G(?<!\\[)(\\w+)(?!\\])";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(template);
while (m.find())
{
System.out.println(m.group());
}
負の後読みと負の先読み、および境界マッチャーの組み合わせを使用します。
(?<!\\[) //negative look behind
(?!\\]) //negative look ahead
(\\w+) //capture group for the word
\\G //is a boundary matcher for marking the end of the previous match
(明確にするために、次の編集をお読みください)
編集1:
次のような状況を説明する必要がある場合:
"chicken [chicken] chicken [chicken]"
正規表現を次のものに置き換えることができます。
String regex = "(?<!\\[)\\b(\\w+)\\b(?!\\])";
編集2:
次のような状況も考慮する必要がある場合:
"[chicken"
"chicken]"
まだ が"chicken"
必要な場合は、次を使用できます。
String pattern = "(?<!\\[)?\\b(\\w+)\\b(?!\\])|(?<!\\[)\\b(\\w+)\\b(?!\\])?";
どちらかの側にブラケットが 1 つしかない 2 つのケースを本質的に説明します。これは|
、or として機能する which と、?
先読み/後読みの後に使用することによってこれを実現します。 where?
は、前の式の 0 または 1 を意味します。
見回さずに:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MatchingTest
{
private static String x = "pig [cow] chicken bull] [grain";
public static void main(String[] args)
{
Pattern p = Pattern.compile("(\\[?)(\\w+)(\\]?)");
Matcher m = p.matcher(x);
while(m.find())
{
String firstBracket = m.group(1);
String word = m.group(2);
String lastBracket = m.group(3);
if ("".equals(firstBracket) && "".equals(lastBracket))
{
System.out.println(word);
}
}
}
}
出力:
pig
chicken
確かにもう少し冗長ですが、読みやすく、理解しやすいと思います。ブラケットのすべての可能な組み合わせを処理しようとする巨大な正規表現よりも確かに簡単です。
これは次のような入力を除外しないことに注意してください[fence tree grass]
。一致していることを示しますtree
。パーサーなしではスキップできません。tree
うまくいけば、これはあなたが処理する必要のあるケースではありません。