Groovy Regex нелегальные персонажи - PullRequest
1 голос
/ 13 июля 2010

У меня есть скрипт Groovy, который преобразует некоторые очень плохо отформатированные данные в XML. Эта часть отлично работает, но она также с радостью передает некоторые символы, которые недопустимы в XML. Поэтому я добавляю некоторый код, чтобы убрать их, и вот откуда возникает проблема.

Код, который не компилируется, таков:

def illegalChars = ~/[\u0000-\u0008]|[\u000B-\u000C]|[\u000E-\u001F]|[\u007F-\u009F]/

Что мне интересно, так это почему? Что я здесь не так делаю? Я протестировал это регулярное выражение в http://regexpal.com/, и оно работает как положено, но я получаю сообщение об ошибке при компиляции в Groovy:

[ОШИБКА] СТРОИТЬ ОШИБКУ [ИНФОРМАЦИЯ] ----------------------------------------------- ------------------------- [INFO] строка 23:26: неожиданный символ: 0x0

Строка выше line 23. Окружающие строки - это объявления переменных, которые я не изменил при работе с регулярным выражением.

Спасибо!

Обновление: Код компилируется, но не фильтруется, как я ожидал. В регулярное выражение я положил регулярное выражение:

[\ u0000- \ u0008 \ u000B- \ u000C \ u000E- \ u001F \ u007F- \ u009F]

и данные испытаний:

name='lang'>E</field><field name='title'>CHEMICAL IMMUNOLOGY AND ALLERGY</field></doc>
<doc><field name='page'>72-88</field><field name='shm'>3146.757500</field><field 
name='pubc'>47</field><field name='cs'>1</field><field name='issue'>NUMBER</field>
<field name='auth'>Dvorak, A.</field><field name='pub'>KARGER</field><field  
 name='rr'>GBP013.51</field><field name='issn'>1660-2242</field><field 
name='class1'>TS</field><field name='freq'>S</field><field 
name='class2'>616.079</field><field name='text'>Subcellular Localization of the 
Cytokines, Basic Fibroblast Growth Factor and Tumor Necrosis Factor- in Mast 
Cells</field><field name='id'>RN170369808</field><field name='volume'>VOL 85</field>
<field name='year'>2005</field><field name='lang'>E</field><field 
name='title'>CHEMICAL IMMUNOLOGY AND ALLERGY</field></doc><doc><field   
name='page'>89-97</field><field name='shm'>3146.757500</field><field 
name='pubc'>47</field><field name='cs'>1</field><field 

Это захват из файла с одним из недопустимых символов, поэтому он немного случайный. Но regexpal выделяет только недопустимый символ, но в Groovy он заменяет даже символы «<» и «>» пустыми строками, поэтому фактически уничтожает весь документ.

Фрагмент кода:

    def List parseFile(File file){
    println "reading File name: ${file.name}"
    def lineCount = 0
    List data = new ArrayList()

    file.eachLine {
        String input ->
        lineCount ++
        String line = input
        if(input =~ illegalChars){
            line = input.replaceAll(illegalChars, " ")
        }
        Map document = new HashMap()
        elementNames.each(){
            token ->
            def val = getValue(line, token)
            if(val != null){
                if(token.equals("ISSUE")){
                    List entries = val.split(";")
                    document.putAt("year",entries.getAt(0).trim())
                    if(entries.size() > 1){
                        document.putAt("volume", entries.getAt(1).trim())
                    }
                    if(entries.size() > 2){
                        document.putAt("issue", entries.getAt(2).trim())
                    }
                } else {
                    document.putAt(token, val)
                }
            }
        }
        data.add(document)
    }

    println "done"
    return data
}

Я не вижу причин, по которым эти двое должны вести себя по-разному; я что-то упустил?

Опять спасибо!

Ответы [ 4 ]

3 голосов
/ 24 апреля 2012

Попробуйте это регулярное выражение, чтобы удалить символ unicode из строки:

/*\\u([0-9]|[a-fA-F])([0-9]|[a-fA-F])([0-9]|[a-fA-F])([0-9]|[a-fA-F])/ 
3 голосов
/ 13 июля 2010
line 23:26: unexpected char: 0x0

Это сообщение об ошибке указывает на эту часть кода:

def illegalChars = ~/[\u0000-...
12345678901234567890123

По какой-то причине компилятору не нравится наличие символа Unicode 0 в исходном коде. Тем не менее, вы должны быть в состоянии исправить это, удвоив косую черту. Это предотвращает выход Unicode на уровне исходного кода и позволяет обработчику регулярных выражений обрабатывать Unicode вместо этого:

def illegals = ~/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F-\\u009F]/

Обратите внимание, что я также объединил классы персонажей в один, а не в качестве альтернативы. Я также удалил определение диапазона, когда они не нужны.

Ссылки


При удвоении косой черты

Вот соответствующая цитата из java.util.regex.Pattern

escape-последовательности Unicode, такие как \u2014 в исходном коде Java, обрабатываются, как описано в JLS 3.3 . Такие escape-последовательности также реализуются непосредственно синтаксическим анализатором регулярных выражений, поэтому экранирование Unicode можно использовать в выражениях, которые читаются из файлов или с клавиатуры. Таким образом, строки "\u2014" и "\\u2014", хотя и не равны, компилируются в один и тот же шаблон, который соответствует символу с шестнадцатеричным значением 0x2014.

Для иллюстрации на Java:

System.out.println("\n".matches("\\u000A")); // prints "true"

Тем не менее:

System.out.println("\n".matches("\u000A"));
// DOES NOT COMPILE!
// "String literal is not properly closed by a double-quote"

Это потому, что \u000A, который является символом новой строки, экранируется во втором фрагменте на уровне исходного кода. Исходный код по существу становится:

System.out.println("\n".matches("
"));
// DOES NOT COMPILE!
// "String literal is not properly closed by a double-quote"

Это недопустимый исходный код Java.

1 голос
/ 14 июля 2010

Хорошо, вот мой вывод:

>>> print "XYZ".replaceAll(
       /[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F-\\u009F]/,
       "-"
    )

---

>>> print "X\0YZ".replaceAll(
       /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/,
       "-"
    )

X-YZ

>>> print "X\0YZ".replaceAll(
       "[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F-\\u009F]",
       "-"
    )

X-YZ

Другими словами, мой \\uNNNN ответ в /pattern/ НЕПРАВИЛЬЕН.Случается так, что 0-\ становится частью диапазона, включая <, > и все заглавные буквы.

\\uNNNN работает только в "pattern", а не в /pattern/.

Я отредактирую свой официальный ответ, основываясь на комментариях к этому «ответу».

Смежные вопросы

0 голосов
/ 13 июля 2010

попробуй

def invalidChars = ~ / [\ u000 1 - \ u0008] | [\ u000B- \ u000C] | [\ u000E- \ u001F] | [\ u007F- \ u009F] / `

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...