Javaregex(Java.util.regex)。搜索美元符号

Javaregex(Java.util.regex)。搜索美元符号,java,regex,special-characters,dollar-sign,Java,Regex,Special Characters,Dollar Sign,我有一个搜索字符串。 当它包含一个美元符号时,我希望捕获其后的所有字符,但不包括点或后续的美元符号。。后者将构成后续匹配。 因此,对于这两个搜索字符串中的任何一个…: "/bla/$V_N.$XYZ.bla"; "/bla/$V_N.$XYZ; 我想返回: 沃恩 XYZ 如果搜索字符串包含%符号,我还想返回%符号对之间的内容 下面的正则表达式似乎可以做到这一点 "%([^%]*?)%"; 推断: 以%开头和结尾 拥有一个捕获组-即() 具有包含除%符号以外的任何内容的字符类(插入符号

我有一个搜索字符串。 当它包含一个美元符号时,我希望捕获其后的所有字符,但不包括点或后续的美元符号。。后者将构成后续匹配。 因此,对于这两个搜索字符串中的任何一个…:

"/bla/$V_N.$XYZ.bla";
"/bla/$V_N.$XYZ;
我想返回:

  • 沃恩
  • XYZ
如果搜索字符串包含%符号,我还想返回%符号对之间的内容

下面的正则表达式似乎可以做到这一点

 "%([^%]*?)%";
推断:

  • 以%开头和结尾
  • 拥有一个捕获组-即()
  • 具有包含除%符号以外的任何内容的字符类(插入符号不推断为字符)
  • 重复-但不贪婪*
在某些语言允许捕获组使用
%1
%2
,Java则使用
反斜杠\number
语法。因此,这个字符串编译并生成输出

我怀疑美元符号和圆点需要转义,因为它们是特殊符号:

  • $
    通常是字符串的结尾
  • 是任何字符的元序列
我试过使用双反斜杠符号\

  • 两者都作为字符类<代码>[^\\.\$%]
  • 并使用或'd符号
    %\124;\\$
试图将这种逻辑结合起来,但似乎什么都做不到

我想知道是否有另一双眼睛可以看到如何解决这个难题

我迄今为止的努力:

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
  public static void main(String[] args) {
        String search = "/bla/$V_N.$XYZ.bla";
        String pattern = "([%\\$])([^%\\.\\$]*?)\\1?";
  /* Either % or $ in first capture group ([%\\$])
   * Second capture group - anything except %, dot or dollar sign
   * non greedy group ( *?)
   * then a backreference to an optional first capture group \\1?
   * Have to use two \, since you escape \ in a Java string.
   */
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(search);
        List<String> results = new ArrayList<String>();
          while (m.find()) 
        { 
          for (int i = 0; i<= m.groupCount(); i++) {
                results.add(m.group(i));
          }
        }
        for (String result : results) {
          System.out.println(result);
        }
  }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.regex.Matcher;
导入java.util.regex.Pattern;
班长{
公共静态void main(字符串[]args){
字符串搜索=“/bla/$V_N.$XYZ.bla”;
字符串模式=“([%\\$])([^%\\.\\$]*?)\\1?”;
/*第一个捕获组([%\\$]中的%或$)
*第二捕获组-除%点或美元符号以外的任何符号
*非贪婪群(*?)
*然后是对可选的第一个捕获组\\1的反向引用?
*必须使用两个\,因为在Java字符串中转义\。
*/
Pattern r=Pattern.compile(Pattern);
匹配器m=r.Matcher(搜索);
列表结果=新建ArrayList();
while(m.find())
{ 
对于(int i=0;i您可以使用

String search = "/bla/$V_N.$XYZ.bla";
String pattern = "[%$]([^%.$]*)";
Matcher matcher = Pattern.compile(pattern).matcher(search);
while (matcher.find()){
    System.out.println(matcher.group(1)); 
} // => V_N, XYZ
请参阅和

注意

  • 模式末尾不需要可选的
    \1?
    。因为它是可选的,所以它不限制匹配上下文,并且是冗余的(因为否定字符类既不能匹配
    $
    也不能匹配
    %
  • [%$]([^%.$]*)
    匹配
    %
    $
    ,然后将任何零个或多个捕获到组1中 除了
    %
    $
    以外的字符。您只需要组1值,因此使用了组(1)
  • 在a中,
    $
    都不是特殊的,因此它们不需要在
    [%.$]
    [%$]
    中转义

  • 我想我需要一个非贪婪搜索。@JGFMK不,你不需要。被求反的字符类已经完成了。我怀疑这将无法匹配对(假设这是一个要求)。例如,请尝试
    “/bla/$V_N%.$XYZ.bla”
    asinput@ernest_k这确实会导致结果中出现一些小问题。您得到的捕获组为空。但是,幸运的是,我的数据总是有%对符号,或者只是以$开头。如果以$开头,则一个点或后续的$或行尾可能是我需要捕获的数据的结尾。我可以始终通过检查l来进行保护组(1)的长度,然后再将其添加到我的结果中。@JGFMK如果需要在结果中避免空字符串,则只需在模式中使用一个
    +
    量词:
    String pattern=“[%$]([^%.$]+);
    。我只使用了
    *
    ,因为我遵循了使用
    *?
    的原始模式逻辑。