Java'da Adlandırılmış Grupları Düzenleme


173

Anladığım kadarıyla java.regexpaketin adlandırılmış gruplar için desteği yok ( http://www.regular-expressions.info/named.html ) , herkes beni yapan bir üçüncü taraf kütüphanesine yönlendirebilir mi?

Jregex'e baktım ama son sürümü 2002'de yapıldı ve java5 altında benim için işe yaramadı (kuşkusuz sadece kısa bir süre denedim).


3
Anlayışınız yanlış. JDK7 adlandırılmış grupları işler.
tchrist

2
@tchrist 2009'da JDK7 yoktu.
Alex78191

Yanıtlar:


275

( Güncelleme : Ağustos 2011 )

As geofflane bahsedildi onun cevabı , Java 7 şimdi adlandırılmış gruplara destek .
tchrist yorumda desteğin sınırlı olduğunu belirtiyor.
O onun büyük yanıtında sınırlamalar ayrıntıları " Java Regex Yardımcısı "

Java 7 regex adlı grup desteği Eylül 2010'da Oracle'ın blogunda sunuldu .

Java 7'nin resmi sürümünde, belirtilen yakalama grubunu destekleyen yapılar şunlardır:

  • (?<name>capturing text) adlandırılmış grup "adı" tanımlamak için
  • \k<name> adlandırılmış bir grup "adı" na başvurmak
  • ${name} Eşleştiricinin değiştirme dizesindeki yakalanan gruba başvurma
  • Matcher.group(String name) yakalanan girdi dizisini verilen "adlandırılmış grup" tarafından döndürmek için.

Java 7 öncesi için diğer alternatifler :


( Orijinal cevap : Ocak 2009 , şimdi sonraki iki bağlantı koptu)

Kendi Regex sürümünüzü kodlamadığınız sürece adlandırılmış gruba başvuramazsınız ...

Gorbush2'nin bu konuda yaptığı tam da budur .

Regex2

( sadece ASCII tanımlayıcıları için göründüğü için, tchrist tarafından tekrar belirtildiği gibi sınırlı uygulama . tchrist sınırlamayı şu şekilde detaylandırır:

aynı isim başına sadece adlandırılmış bir gruba sahip olmak (her zaman üzerinde kontrolünüz yoktur!) ve bunları normal ifade içi özyineleme için kullanamamak.

Not: Regexp Power , PCRE özellikleri ve Dengeli Parantezlerle Eşleşen Dizelerde belirtildiği gibi Perl ve PCRE normal ifadelerinde gerçek normal ifade özyineleme örneklerini bulabilirsiniz )

Misal:

Dize:

"TEST 123"

RegExp:

"(?<login>\\w+) (?<id>\\d+)"

Giriş

matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login

değiştirmek

matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____ 

(uygulamadan alıntı)

public final class Pattern
    implements java.io.Serializable
{
[...]
    /**
     * Parses a group and returns the head node of a set of nodes that process
     * the group. Sometimes a double return system is used where the tail is
     * returned in root.
     */
    private Node group0() {
        boolean capturingGroup = false;
        Node head = null;
        Node tail = null;
        int save = flags;
        root = null;
        int ch = next();
        if (ch == '?') {
            ch = skip();
            switch (ch) {

            case '<':   // (?<xxx)  look behind or group name
                ch = read();
                int start = cursor;
[...]
                // test forGroupName
                int startChar = ch;
                while(ASCII.isWord(ch) && ch != '>') ch=read();
                if(ch == '>'){
                    // valid group name
                    int len = cursor-start;
                    int[] newtemp = new int[2*(len) + 2];
                    //System.arraycopy(temp, start, newtemp, 0, len);
                    StringBuilder name = new StringBuilder();
                    for(int i = start; i< cursor; i++){
                        name.append((char)temp[i-1]);
                    }
                    // create Named group
                    head = createGroup(false);
                    ((GroupTail)root).name = name.toString();

                    capturingGroup = true;
                    tail = root;
                    head.next = expr(tail);
                    break;
                }

yukarıdaki her iki bağlantı bozuk görünüyor?
Jonas

Bu kod buggy. ASCII tanımlayıcılarını arıyor. Bu yanlış. Java bir tanımlayıcı izin bir şey arıyor olmalı !!
tchrist

1
Sadece FYI, bu kadar vicdanlı göründüğünüz için, sınırlı bölüm ASCII ve Unicode isimleri hakkında çok fazla değil, çünkü aynı isim başına sadece bir adlandırılmış gruba sahip olmakla ilgilidir (her zaman üzerinde kontrolünüz yoktur!) Ve regex özyineleme için bunları kullanamamak.
tchrist

@tchrist: bu hassasiyet için teşekkürler (dahil). Ayrıca, "Java Regex yardımcısı" konusundaki yıldız yanıtınıza bir bağlantı ekledim (oylandı).
VonC

Java'da Matcher nesnesi için matcher.name (int index) yöntemi yoktur ??
ot0


27

Evet ama dağınık güneş derslerini hacklemek. Daha basit bir yol var:

http://code.google.com/p/named-regexp/

named-regexp, standart JDK düzenli ifadeleri uygulaması için ince bir pakettir.

Java 5 ve 6 ile kullanılabilir (jenerikler kullanılır).

Java 7 adlı yakalama gruplarını işleyecektir, bu nedenle bu proje uzun sürmez.


1
Çok kötü bu GWT içinde kullanılamaz.
Sakuraba

4
Check out GitHub çatal orijinalinden birçok hata düzeltmeleri bu projenin. Maven Central'da da ağırlanıyor.
tony19

1
Benim durumumda sadece bir uyarı, Github'daki tony19 çatalı Android'de 0.1.8'den beri çalışmıyor.
Chuck D

2
@RubberMallet, Android'e özgü sorun düzeltildi ve 0.1.9'da olacak.
tony19


2

Önceden java7 çalışan kişiler için, adlandırılmış gruplar tarafından desteklenen joni (Java portu Oniguruma regexp'in kütüphanesine). Belgeler seyrek, ama bizim için iyi çalıştı.
İkili dosyalar Maven ( http://repository.codehaus.org/org/jruby/joni/joni/ ) aracılığıyla edinilebilir .


Yukarıda Ryan tarafından belirtilen joni seçeneği ile ilgileniyorum - adlandırılmış yakalama gruplarını kullanarak herhangi bir kod parçacığı var mı - temel eşleştirme ve düzgün çalışmak için arama başardı - ama hangi yöntemi kullanacağımı görmüyorum groupNames'e erişebilir veya grup adını kullanarak bir yakalamanın değerini elde edebilirsiniz.
malsmith

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.