如何使用正则表达式匹配某种类型的单词之前的所有内容

时间:2009-02-17 23:48:39

标签: java regex

我是正则表达式的新手。

是否可以匹配符合特定条件的单词之前的所有内容:

E.g。

这是一个测试 - - +++这是一个测试

我希望它遇到一个以大写字母开头而下一个字符为小写字母的单词。这构成了一个恰当的词。我想在那个词之前删除所有内容。

上面的例子应该产生:这是一个测试

我只想进行此处理,直到找到正确的单词然后停止。

任何帮助都将不胜感激。

由于

5 个答案:

答案 0 :(得分:47)

替换

^.*?(?=[A-Z][a-z])

用空字符串。这适用于ASCII输入。对于非ASCII输入(Unicode,其他语言),适用不同的策略。

解释

.*?    Everything, until
(?=    followed by
[A-Z]  one of A .. Z and
[a-z]  one of a .. z
)

支持Java Unicode的变体是:

^.*?(?=\p{Lu}\p{Ll})

答案 1 :(得分:3)

稍微吵醒后,您不需要删除任何内容,甚至不需要创建子组 - 只需找到答案中其他地方表达的模式。这是一个完整的例子:

import java.util.regex.*;

public class Test
{
    public static void main(String args[])
    {
        Pattern pattern = Pattern.compile("[A-Z][a-z].*");

        String original = "THIS IS A TEST - - +++ This is a test";
        Matcher match = pattern.matcher(original);
        if (match.find())
        {
            System.out.println(match.group());
        }
        else
        {
            System.out.println("No match");
        }        
    }
}

编辑:原始答案

这看起来正在做正确的事情:

import java.util.regex.*;

public class Test
{
    public static void main(String args[])
    {
        Pattern pattern = Pattern.compile("^.*?([A-Z][a-z].*)$");

        String original = "THIS IS A TEST - - +++ This is a test";
        String replaced = pattern.matcher(original).replaceAll("$1");

        System.out.println(replaced);
    }
}

基本上,诀窍不是在正确的单词之前忽略所有内容 - 它是从正确的单词开始对所有内容进行分组,并用该组替换整个文本。

上述内容将因"*** FOO *** I am fond of peanuts"而失败,因为“I”不会被视为正确的单词。如果你想修复它,将[a-z]更改为[a-z \ s],这将允许空格而不是字母。

答案 2 :(得分:1)

我知道我对此的看法真的不那么受欢迎,所以如果你愿意的话,你们可以向我投票,但我必须咆哮一点(这包含一个解决方案,只是不是海报的方式要求)。

我真的不明白为什么人们如此迅速地去正则表达式。

我已经做了很多字符串解析(用于屏幕抓取vt100菜单屏幕),我从来没有发现一个案例,正则表达式比编写代码容易得多。 (也许一对夫妻会更容易,但不会太多。)

我有点明白,一旦你了解它们,它们应该会更容易 - 但是你会看到有人问这样的问题,并意识到每个程序员都不容易看到它。如果它花了10分钟的时间在某个地方花费了1个程序员,那么即使你花了5分钟写5行,它也只有编码就会有巨大的净损失。

所以它需要文档 - 如果处于同一级别的人遇到它,他将无法在没有域外知识的情况下修改它,即使是文档也是如此。

我的意思是如果海报不得不询问一个微不足道的案例 - 那就不是一件小事了。

public String getRealText(String scanMe) {
    for(int i=0 ; i < scanMe.length ; i++)
        if( isUpper(scanMe[i]) && isLower(scanMe[i+1]) )
            return scanMe.subString(i);
return null; }

我的意思是它有5行,但它比大多数(所有?)RE解析器更简单,可读,更快。一旦在方法中包装了正则表达式并对其进行了评论,大小的差异就无法衡量。时间上的差异 - 很明显,海报显然会花费更少的时间 - 因为它可能是下一个遇到他的代码的人。

这个字符串操作是使用指针在C中更容易的操作之一 - 由于测试函数是C中的宏,因此它会更快。

顺便说一下,确保你在第二个插槽中寻找一个空格,而不仅仅是一个小写变量,否则你会错过任何以A或I开头的行。

答案 3 :(得分:0)

然后你可以做这样的事情

'.*([A-Z][a-z].*)\s*'

.* matches anything
( [A-Z] #followed by an uper case char 
  [a-z] #followed by a lower case 
  .*)   #followed by anything
  \s*   #followed by zeror or more white space

我想要的是你想要的

答案 4 :(得分:0)

  

([A-Z] [A-Z]。+)

会匹配:

这是一个文本