我试图使用Java正则表达式从以下字符串中提取粗体子字符串:
音乐作品| 与| 作曲家| James Hetfield(音乐家)
我开始使用此代码,但这不起作用.我不确定我错过了什么:
final Pattern pattern = Pattern.compile("| (.+?) (musician)");
final Matcher matcher = pattern.matcher("music works | with | composer | James Hetfield (musician)");
matcher.find();
System.out.println(matcher.group(1)); // Prints String I want to extract
Run Code Online (Sandbox Code Playgroud)
思考?
根据您使用(和)创建组的事实,我假设您知道括号是正则表达式中的特殊字符.但是你知道特殊字符与文本中的文字不匹配吗?请注意,(.*)不需要匹配的文本以括号开头和结尾.
要让特殊字符与其文字匹配,您需要转义它们.您可以通过多种方式实现这一目标,例如:
\在它们之前添加(需要以String编写"\\"),[ ]来创建只代表一个字符的字符类 - 特殊字符. 同样|是正则表达式中的特殊字符,它代表OR运算符,因此您还需要转义它.
另一件事是.+?尽管不情愿,但是| (.+?)从第一次|发现开始匹配,这意味着它也可以接受其他|直到(musician)找到.换句话说,这样的正则表达式会发现这个aprt
music works | with | composer | James Hetfield (musician)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
因此,为了防止接受|你接受的而(musician)不是.使用[^|]它之间的其他管道()- 接受任何字符的字符类除外|.
所以试试这个模式:
final Pattern pattern = Pattern.compile("\\| ([^|]+) \\(musician\\)");
Run Code Online (Sandbox Code Playgroud)
更新:
如果你的正则表达式应该匹配的部分可能没有|它(假设它在你的文本的开头),那么你可以简单\\|地通过用括号括起来并?在它之后添加以使该部分可选而使其成为可选部分.您也可以将它放在非捕获组中,它将([^|]+)仍然是索引1的组,这将使您的代码保持不变(您不必更改matcher.gorup(1)为matcher.group(2)).
所以你可以试试
final Pattern pattern = Pattern.compile("(?:\\| )?([^|]+) \\(musician\\)");
Run Code Online (Sandbox Code Playgroud)