Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何添加Java正则表达式实现中缺少的特性?_Java_Regex - Fatal编程技术网

如何添加Java正则表达式实现中缺少的特性?

如何添加Java正则表达式实现中缺少的特性?,java,regex,Java,Regex,我是Java新手。作为一名.Net开发人员,我非常习惯.Net中的Regex类。Regex(正则表达式)的Java实现不错,但缺少一些关键特性 我想为Java创建自己的helper类,但我想可能已经有一个可用的了。那么,在Java中是否有任何免费且易于使用的产品可供Regex使用,或者我是否应该自己创建一个 如果我要写我自己的类,你认为我应该在哪里分享给其他人使用 [编辑] 有人抱怨我没有用当前的Regex类解决这个问题。我会尽力澄清我的问题 在.Net中,正则表达式的使用比在Java中更容易

我是Java新手。作为一名.Net开发人员,我非常习惯.Net中的
Regex
类。
Regex
(正则表达式)的Java实现不错,但缺少一些关键特性

我想为Java创建自己的helper类,但我想可能已经有一个可用的了。那么,在Java中是否有任何免费且易于使用的产品可供Regex使用,或者我是否应该自己创建一个

如果我要写我自己的类,你认为我应该在哪里分享给其他人使用


[编辑]

有人抱怨我没有用当前的
Regex
类解决这个问题。我会尽力澄清我的问题

在.Net中,正则表达式的使用比在Java中更容易。由于这两种语言都是面向对象的,并且在许多方面非常相似,因此我希望在这两种语言中使用regex时有类似的经验。不幸的是,情况并非如此


下面是一段比较Java和C语言的代码。第一个是C#,第二个是Java:

在C#中:

string source=“我包的颜色与我衬衫的颜色匹配!”;
字符串模式=“colou?r”;
foreach(Regex.Matches中的匹配(源,模式))
{
控制台写入线(匹配值);
}
在Java中:

String source=“我包的颜色与我衬衫的颜色匹配!”;
字符串模式=“colou?r”;
Pattern p=Pattern.compile(Pattern);
匹配器m=p.Matcher(源);
while(m.find())
{
System.out.println(source.substring(m.start(),m.end());
}
在上面的示例代码中,我试图对两种语言都公平

这里首先要注意的是
Match
类的
.Value
成员(与Java中使用
.start()
.end()
相比)

当我可以调用像
Regex.Matches
Regex.Match
等静态函数时,为什么要创建两个对象

在更高级的用法中,差异表现得更多。看看方法
、字典长度、
捕获
索引
长度
成功
,等等。在我看来,这些都是Java应该具备的非常必要的特性


当然,所有这些特性都可以通过自定义代理(helper)类手动添加。这就是我问这个问题的主要原因。在Perl中,我们没有
Regex
的微风,但至少我们可以使用.Net方法来
Regex
,我认为这是非常巧妙的设计。

孩子,我听到你说的了吗Alireza!正则表达式在没有太多语法变体的情况下已经足够混乱了。我也做了很多C#而不是Java编程,我也有同样的问题

我发现这很有帮助:
-这是一个Java的替代正则表达式实现列表,经过基准测试。

从您编辑的示例中,我现在可以看到您想要什么。我也很同情你。Java的正则表达式与Ruby或Perl中的便利性相差很远。他们几乎总是这样;这是无法修复的,所以我们永远都要面对这种混乱局面——至少在Java中是这样。其他JVM语言在这方面做得更好,尤其是Groovy。但它们仍然存在一些固有的缺陷,只能走这么远

从哪里开始?字符串类有一些所谓的方便方法:
matches
replaceAll
replaceFirst
split
。这些在小程序中有时是可以的,这取决于您如何使用它们。然而,他们确实有几个问题,你似乎已经发现了。下面是这些问题的部分列表,以及可以和不能解决的问题

  • 这个方法的名字很奇怪,叫做“matches”,但它需要在两边填充正则表达式以匹配整个字符串。这种反直觉的感觉与以前任何语言中使用的“匹配”一词的含义相反,并且不断地咬人。传递到其他3种方法中的模式与此方法的工作方式非常不同,因为在其他3种方法中,它们的工作方式与正常模式在其他地方的工作方式相同;只是不在
    匹配项中
    。这意味着您不能只是复制您的模式,即使是在同一个该死的类中的方法中!而且,没有一种方便的方法可以像世界上其他匹配者那样找到匹配者。
    matches
    方法的调用应该类似于
    FullMatch
    ,并且应该在String类中添加
    PartialMatch
    find
    方法

  • 没有允许您传入
    模式的API。请编译
    标志以及用于String类的4个与模式相关的便利方法的字符串。这意味着您必须依赖字符串版本,如
    (?i)
    (?x)
    ,但这些版本并不适用于所有可能的模式编译标志。至少可以说,这是非常不方便的

  • split
    方法在边缘情况下返回的结果与
    split
    在Java借用split的语言中返回的结果不同。这是个鬼鬼祟祟的小把戏。如果拆分空字符串,您认为返回列表中应该返回多少元素,嗯?Java制造了一个应该有返回元素的假返回元素,这意味着您无法区分合法结果和伪造结果。这是一个严重的设计缺陷,在一个
    :“
    上分裂,你无法分辨
    的输入与
    “:”
    的输入之间的区别。哎呀!人们从来没有测试过这种东西吗?再说一次,坏的和根本不可靠的行为是不可改变的:你永远不能改变事情,即使是坏的事情。不可以
       String rx =
              "(?= ^ \\p{Lu} [_\\pL\\pM\\d\\-] + \$)\n"
            + "   # next is a big can't-have set    \n"
            + "(?! ^ .*                             \n"
            + "    (?: ^     \\d+              $    \n"
            + "      | ^ \\p{Lu} - \\p{Lu}     $    \n"
            + "      | Invitrogen                   \n"
            + "      | Clontech                     \n"
            + "      | L-L-X-X    # dashes ok       \n"
            + "      | Sarstedt                     \n"
            + "      | Roche                        \n"
            + "      | Beckman                      \n"
            + "      | Bayer                        \n"
            + "    )      # end alternatives        \n"
            + "    \\b    # only on a word boundary \n"
            + ")          # end negated lookahead   \n"
            ;
    
    public class Regex {
    
        /**
         * @param source 
         *        the string to scan
         * @param pattern
         *        the regular expression to scan for
         * @return the matched 
         */
        public static Iterable<String> matches(final String source, final String pattern) {
            final Pattern p = Pattern.compile(pattern);
            final Matcher m = p.matcher(source);
            return new Iterable<String>() {
                @Override
                public Iterator<String> iterator() {
                    return new Iterator<String>() {
                        @Override
                        public boolean hasNext() {
                            return m.find();
                        }
                        @Override
                        public String next() {
                            return source.substring(m.start(), m.end());
                        }    
                        @Override
                        public void remove() {
                            throw new UnsupportedOperationException();
                        }
                    };
                }
            };
        }
    
    }
    
    public class RegexTest {
    
        @Test
        public void test() {
           String source = "The colour of my bag matches the color of my shirt!";
           String pattern = "colou?r";
           for (String match : Regex.matches(source, pattern)) {
               System.out.println(match);
           }
        }
    }