Java 如何获取第一个和最后一个连字符之间的字符串

Java 如何获取第一个和最后一个连字符之间的字符串,java,regex,string,Java,Regex,String,我试图制作一个程序,如果给定的字符串中有两个破折号,则返回前两个破折号之间的文本。如果它没有至少两个破折号,它将返回它不存在。我有一根绳子 String s = "I AM -VERY- HUNGRY" 我希望我的程序返回非常高的值,在两个破折号之间。这是到目前为止我的代码 public static String middleText(String sentence) { int count = 0; for (int i = 0; i < sentence.leng

我试图制作一个程序,如果给定的字符串中有两个破折号,则返回前两个破折号之间的文本。如果它没有至少两个破折号,它将返回它不存在。我有一根绳子

String s = "I AM -VERY- HUNGRY"
我希望我的程序返回非常高的值,在两个破折号之间。这是到目前为止我的代码

public static String middleText(String sentence)
   {
   int count = 0;
   for (int i = 0; i < sentence.length(); i++)
   {
     if (sentence.charAt(i) == '-')
     {
        count++;
     }
   } 
   if (count >= 2)
   {
     return sentence.substring(sentence.indexOf("-") + 1);
   }
   else
   {
     return "DOES NOT EXIST";
   }
}  
公共静态字符串中间文本(字符串语句)
{
整数计数=0;
for(int i=0;i<句子长度();i++)
{
如果(句子.字符(i)='-')
{
计数++;
}
} 
如果(计数>=2)
{
返回语句.子字符串(语句.indexOf(“-”)+1);
}
其他的
{
返回“不存在”;
}
}  

但是,这段代码不会产生我想要的输出。如果我将字符串
I AM-VERY-hunger
放入此代码中,它将返回
VERY-hunger
。我怎样才能使它只在第二个破折号前抓取文本

您可以使用以下行:

return sentence.substring(sentence.indexOf("-")+1, sentence.lastIndexOf("-"));

或者使用正则表达式。有关此案例的具体正则表达式,请参见位于的链接

它与以下内容相匹配:

  • \w+
    表示至少一次的任何字母
    +
  • ()
    正在捕获组
  • -(\w+)-
    捕获
    -
    字符之间的一个或多个字母
组合
模式
匹配器
以获得结果

public static String middleText(String sentence) {
    Pattern pattern = Pattern.compile("-(\w)-");
    Matcher matcher = pattern.matcher(sentence);
    if (matcher.find()) {
        return matcher.group(1);
    } else {
        return "DOES NOT EXIST";
    }
}

您可以为此使用模式和匹配器(java.util.regex)


您需要使用
indexOf
获取第一个连字符的索引,并使用
lastIndexOf
获取最后一个连字符的索引。所以也许是这样的:

int firstIndex = sentence.indexOf("-");
int lastIndex = sentence.lastIndexOf("-");
return sentence.substring(firstIndex+1, lastIndex);

(注意:此代码未经测试,不包括您提到的那种错误检查。)

只需使用字符串拆分方法即可。使用字符串“-”作为分隔符,如果结果数组的长度大于等于3,则数组的第二个成员就是结果:

public String myMatchFinder(String arg) {
    String result = null;
    String res[] = arg.split("-", 3);
    if(res.length == 3) {
      result = res[1];
    } else {
      throw new RuntimeException("No matches found");
    }
    return result;
}

如果找不到图案,“else”块将起作用。因此,在本例中,异常被作为不匹配的指示符抛出,而不是返回一个可能会与实际结果混淆的字符串。(假设您的arg字符串是“您好-未找到匹配项-再见”。在这种情况下,字符串“未找到匹配项”将是您的实际结果)。所以,在抛出异常的情况下,您可以在调用代码中捕获它,并以任何方式将其作为错误处理

以及单线解决方案

return Optional.of(sentence)
    .map(Pattern.compile("(?<=-).*?(?=-)")::matcher)
    .filter(Matcher::find)
    .map(Matcher::group)
    .orElse("DOES NOT EXIST");
返回可选的.of(句子)

.map(Pattern.compile((?)如果字符串格式一致-始终有两个连字符,其中有一个值-您只需将
.replaceFirst
^[^-]*-(.*)-[^-]*$
正则表达式模式和替换模式中的
$1
占位符一起使用即可:

String s = "I AM -VERY- HUNGRY"
String result = s.replaceFirst("(?s)^[^-]*-(.*)-[^-]*$", "$1");
请参阅和

详细信息

  • (?s)
    -点所有修饰符
  • ^
    -字符串的开头
  • [^-]*
    -0+字符,而非
    -
  • -
    -连字符
  • (.*)
    -第1组(用替换模式中的
    $1
    表示)-尽可能多的任何0+字符
  • -
    -连字符
  • [^-]*
    -0+字符,而非
    -
  • $
    -字符串结束

如果可以有任何类型的连字符,请在代码中使用
\\p{Pd}
而不是
-

跟踪字符的索引-。然后,在这些数字之间取一个子字符串…
句子。indexOf(“-”
返回第一个字符的位置”-"只有一个参数的
substring
将为您提供从该位置开始直到结束的字符串。提示:您的方法应该在一切正常时返回字符串。因此返回字符串错误消息确实是一个坏主意!使用该方法的代码必须检查返回的字符串是否不存在,以确定发生了什么on.Bad style!如果使用了
find()
,则不需要在开头和结尾处使用
*
。这也更直观,因为您确实在尝试在破折号之间查找文本。您是想调用
find()
?否则,它仅在字符串以破折号开头和结尾时才起作用。是的,我的意思是
find()
。很抱歉,谢谢您的编辑。这只是一个简单的新手示例。因此,这将很清楚。我当然不会将此作为真正的代码编写。我也(几乎)在同一个方法中永远不会有多个返回,但这是一个快速而肮脏的演示。因此,从技术上来说,你是正确的,但你只是在细节上挑拣,而原理解决方案是正确的,并且是直观的演示。好吧,这更好,我同意,只剩下一件事——消息中有一个输入错误。你应该解释一下还有什么问题杰克正在做什么。
return Optional.of(sentence)
    .map(Pattern.compile("(?<=-).*?(?=-)")::matcher)
    .filter(Matcher::find)
    .map(Matcher::group)
    .orElse("DOES NOT EXIST");
String s = "I AM -VERY- HUNGRY"
String result = s.replaceFirst("(?s)^[^-]*-(.*)-[^-]*$", "$1");