Java regex соответствует имени файла (#). Extension [duplicate]

Это зависит от объема ваших тестов. Тесты высокого уровня (интеграция, приемка и т. Д.), Вероятно, должны быть размещены в отдельном пакете, чтобы гарантировать, что вы используете пакет через экспортированный API.

Если у вас большой пакет с большим количеством внутренних компонентов, которые должны быть подвергнуты тестированию, затем используйте один и тот же пакет для своих тестов. Но это не приглашение для ваших тестов на доступ к любому частному состоянию. Это сделало бы рефакторинг кошмаром. Когда я пишу structs в go , я часто реализую интерфейсы. Это те методы интерфейса, которые я вызываю из своих тестов, а не все вспомогательные методы / функции по отдельности.

289
задан Matt 13 September 2008 в 00:36
поделиться

8 ответов

Поскольку Java 1.5, да :

Pattern.quote("$5");
411
ответ дан Yannick Blondeau 25 August 2018 в 18:47
поделиться
  • 1
    Пожалуйста, не делайте этого, чтобы избежать самой строки, но обертывает ее с помощью \Q и \E. Это может привести к неожиданным результатам, например Pattern.quote("*.wav").replaceAll("*",".*") приведет к \Q.*.wav\E, а не .*\.wav, как вы могли ожидать. – Paramaeleon 16 January 2013 в 15:27
  • 2
    @Paramaeleon Почему вы ожидаете, что foo (x) .bar () == x.bar ()? – Michael 7 August 2013 в 23:11
  • 3
    @Paramaeleon Я думаю, что вы недопонимаете прецедент. – vikingsteve 12 November 2013 в 12:50
  • 4
    Я просто хочу отметить, что этот способ экранирования применяется также в выражениях, которые вы вводите впоследствии . Это может быть удивительно. Если вы сделаете "mouse".toUpperCase().replaceAll("OUS","ic"), он вернет MicE. Вы бы не ожидали, что он вернет MICE, потому что вы не применили toUpperCase() к ic. В моем примере quote() применяется к вставке .* на replaceAll(). Вы должны сделать что-то еще, возможно, .replaceAll("*","\\E.*\\Q") будет работать, но это противоречит. – Paramaeleon 12 November 2013 в 16:53
  • 5
    @Paramaleon Если это сработало, добавив отдельные escape-последовательности, ваш первоначальный пример все равно не будет делать то, что вы хотели ... если бы он экранировал символы индивидуально, он превратил бы *.wav в шаблон регулярного выражения \*\.wav, а replaceAll превратился бы его в \.*\.wav, то есть он будет соответствовать файлам, имя которых состоит из произвольного количества периодов, за которыми следует .wav. Скорее всего, вам понадобилось бы replaceAll("\\*", ".*"), если бы они пошли с более хрупкой реализацией, которая полагается на распознавание всех возможных активных часовых символов и их экранирование индивидуально ... было бы намного проще? – Theodore Murdock 12 June 2015 в 21:19

Pattern.quote («blabla») прекрасно работает.

Функция Pattern.quote () работает красиво. Он заключает предложение с символами «\ Q» и «\ E», и если он убегает «\ Q» и «\ E». Однако, если вам нужно выполнить эскиз реального регулярного выражения (или пользовательское экранирование), вы можете использовать этот код:

String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));

Этот метод возвращает: Some / \ s / wText * / \ , **

Код, например, и тесты:

String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
1
ответ дан Adam111p 25 August 2018 в 18:47
поделиться
Символ

^ (Negation) используется для сопоставления с тем, что отсутствует в группе символов. Информация о отрицании

Регулярные выражения

0
ответ дан Akhil Kathi 25 August 2018 в 18:47
поделиться

Я думаю, что вам нужно \Q$5\E. Также см. Pattern.quote(s), введенные в Java 5.

S Шаблон javadoc для деталей.

13
ответ дан Alex Shesterov 25 August 2018 в 18:47
поделиться
  • 1
    Мне любопытно, есть ли разница между этим и использованием флага LITERAL, поскольку javadoc говорит, что нет встроенного флага для включения и отключения LITERAL: java.sun.com/j2se/1.5.0/docs/api / Java / Util / регулярное выражение / & hellip; – Chris Mazzola 6 August 2009 в 21:51
  • 2
    Обратите внимание, что буквально использование \ Q и \ E является прекрасным, если вы знаете свой ввод. Pattern.quote (s) также обрабатывают случай, когда ваш текст содержит эти последовательности. – Jeremy Huiskamp 14 February 2011 в 03:03

Возможно, слишком поздно ответить, но вы также можете использовать Pattern.LITERAL, который будет игнорировать все специальные символы при форматировании:

Pattern.compile(textToFormat, Pattern.LITERAL);
24
ответ дан Androidme 25 August 2018 в 18:47
поделиться
  • 1
    Это особенно приятно, потому что вы можете комбинировать его с Pattern.CASE_INSENSITIVE – mjjaniec 4 August 2017 в 07:04

Разница между Pattern.quote и Matcher.quoteReplacement не была мне понятна, прежде чем я увидел следующий пример

s.replaceFirst(Pattern.quote("text to replace"), 
               Matcher.quoteReplacement("replacement text"));
96
ответ дан fabian 25 August 2018 в 18:47
поделиться
  • 1
    В частности, Pattern.quote заменяет специальные символы в строках поиска regex, например. | + () И т. Д., А Matcher.quoteReplacement заменяет специальные символы в строках замещения, например \ 1 для обратных ссылок. – Steven 18 November 2011 в 20:12
  • 2
    Я не согласен. Pattern.quote обертывает свой аргумент с помощью \ Q и \ E. Это не исключает специальных символов. – David Medinets 7 February 2015 в 00:28
  • 3
    Matcher.quoteReplacement («4 $ & amp;% $») производит «4 \ $ & amp;% \ $». Он ускользает от специальных символов. – David Medinets 7 February 2015 в 00:31
  • 4
    Другими словами: quoteReplacement заботится только о двух символах $ и \ , которые могут, например, использоваться в замещающих строках как обратные ссылки $1 или \1. Поэтому он не должен использоваться для выключения / цитирования регулярного выражения. – SebastianH 14 February 2016 в 11:13
  • 5
    Потрясающие. Вот пример, где мы хотим заменить $Group$ на T$UYO$HI. Символ $ является особым как в шаблоне, так и в замене: "$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI")) – arun 1 March 2016 в 22:10

Прежде всего, если

  • вы используете replaceAll ()
  • , вы НЕ используете Matcher.quoteReplacement ()
  • текст, который должен быть замещенный в включает $ 1

, он не поместит 1 в конец. Он будет искать регулярное выражение поиска для первой группы соответствия и sub THAT. Вот что означает $ 1, $ 2 или $ 3 в заменяющем тексте: сопоставление групп с шаблоном поиска.

Я часто подключаю длинные строки текст в .properties файлы, а затем создавать темы электронной почты и тела из них. В самом деле, это, по-видимому, является способом по умолчанию для i18n в Spring Framework. Я помещал теги XML в качестве заполнителей в строки, и я использую replaceAll () для замены тегов XML значениями во время выполнения.

Я столкнулся с проблемой, когда пользователь вводил доллары и центы фигура со знаком доллара. replaceAll (), забитый на нем, со следующим отображением в stracktrace:

java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)

В этом случае пользователь ввел «$ 3» где-то на своем входе, а replaceAll () отправился искать в поиске regex для третьей сопоставимой группы, не нашел ее и не запутался.

Учитывая:

// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input

заменяя

msg = msg.replaceAll("<userInput \\/>", userInput);

на

msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));

решил проблему. Пользователь может вводить любые символы, включая знаки доллара, без проблем. Он вел себя так, как вы ожидали.

10
ответ дан Meower68 25 August 2018 в 18:47
поделиться

Чтобы иметь защищенный шаблон, вы можете заменить все символы на «\\\\», за исключением цифр и букв. И после этого вы можете поместить в этот защищенный шаблон свои специальные символы, чтобы заставить этот шаблон работать не как глупый цитируемый текст, а действительно как паттен, но ваш собственный. Без специальных символов пользователя.

public class Test {
    public static void main(String[] args) {
        String str = "y z (111)";
        String p1 = "x x (111)";
        String p2 = ".* .* \\(111\\)";

        p1 = escapeRE(p1);

        p1 = p1.replace("x", ".*");

        System.out.println( p1 + "-->" + str.matches(p1) ); 
            //.*\ .*\ \(111\)-->true
        System.out.println( p2 + "-->" + str.matches(p2) ); 
            //.* .* \(111\)-->true
    }

    public static String escapeRE(String str) {
        //Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
        //return escaper.matcher(str).replaceAll("\\\\$1");
        return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
    }
}
4
ответ дан toinetoine 25 August 2018 в 18:47
поделиться
  • 1
    Вам не нужно избегать пробелов. Таким образом, вы можете изменить свой шаблон на & quot; ([^ a-zA-z0-9]) & quot ;. – Erel Segal-Halevi 7 April 2013 в 09:21
  • 2
    Малая опечатка, большие последствия: & quot; ([^ a-zA-z0-9]) & quot; также не совпадает (т. е. не убегает) [, \,], ^, который вы, безусловно, хотите избежать! Опечатка - это вторая «z», которая должна быть «Z», в противном случае все, начиная от ASCII 65 до ASCII 122 – Zefiro 29 May 2015 в 16:04
Другие вопросы по тегам:

Похожие вопросы: