W Pythonie, podczas formatowania łańcucha, mogę wypełniać symbole zastępcze nazwą, a nie pozycją, na przykład:
print "There's an incorrect value '%(value)s' in column # %(column)d" % \
{ 'value': x, 'column': y }
Zastanawiam się, czy jest to możliwe w Javie (miejmy nadzieję, bez zewnętrznych bibliotek)?
java
string-formatting
Andy
źródło
źródło
%s
była powszechna praktyka. en.wikipedia.org/wiki/Printf_format_string#History Należy również zauważyć, że niektóre IDE i FindBugs mogą automatycznie wykrywać niezgodne liczby% si% d, ale nadal wolałbym nazwane pola.Odpowiedzi:
StrSubstitutor of jakarta commons lang to lekki sposób na zrobienie tego, pod warunkiem, że twoje wartości są już poprawnie sformatowane.
http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/text/StrSubstitutor.html
Powyższe skutkuje:
„W kolumnie 2 jest nieprawidłowa wartość„ 1 ””
Używając Mavena, możesz dodać tę zależność do swojego pom.xml:
źródło
${arg}
) zamiast niestandardowej powyżej (%(arg)
), to wyrażenie regularne nie zostanie skompilowane, co jest pożądanym efektem.niezupełnie, ale możesz użyć MessageFormat do wielokrotnego odwoływania się do jednej wartości:
Powyższe można również zrobić za pomocą String.format (), ale uważam, że czyścisz składnię messageFormat, jeśli potrzebujesz zbudować złożone wyrażenia, a ponadto nie musisz przejmować się typem obiektu, który umieszczasz w ciągu
źródło
MessageFormat
jest świetny, ale uciążliwy dla stosunkowo dużej zawartości jsonKolejny przykład Apache Common StringSubstitutor dla prostego nazwanego symbolu zastępczego.
źródło
replaceIn
zastępowanie wartości w buforze: StringBuilder lub TextStringBuilder. Przy takim podejściu cała zawartość pliku nie zostanie załadowana do pamięci.Możesz użyć biblioteki StringTemplate , oferuje to, czego chcesz i wiele więcej.
źródło
'
char:unexpected char: '''
W bardzo prostych przypadkach możesz po prostu użyć zakodowanej na stałe zamiany String, nie ma potrzeby posiadania tam biblioteki:
UWAGA : chciałem tylko pokazać najprostszy możliwy kod. Oczywiście NIE używaj tego do poważnego kodu produkcyjnego, w którym bezpieczeństwo ma znaczenie, jak stwierdzono w komentarzach: ucieczka, obsługa błędów i bezpieczeństwo są tutaj problemem. Ale w najgorszym przypadku już wiesz, dlaczego użycie `` dobrej '' biblioteki jest wymagane :-)
źródło
Dzięki za pomoc! Korzystając ze wszystkich wskazówek, napisałem procedurę, która robi dokładnie to, czego chcę - formatowanie ciągów w stylu Pythona za pomocą słownika. Ponieważ jestem nowicjuszem w Javie, wszelkie wskazówki są mile widziane.
źródło
formatPos
nie może zawieraćformatKey
.To jest stary wątek, ale tak dla przypomnienia, możesz również użyć stylu Java 8, na przykład:
Stosowanie:
Wynik będzie:
źródło
.reduce()
pośrednie wyniki podstawiania traktują jako własne ciągi formatujące, to rozwiązanie jest podatne na ataki na ciągi formatujące . Każde poprawne rozwiązanie powinno wykonać jedno przejście przez ciąg formatu.Przykład:
źródło
.replaceAll()
wywołań zwrotnych zastępowania ciągów .Jestem autorem małej biblioteki, która robi dokładnie to, co chcesz:
Lub możesz połączyć argumenty:
źródło
Metoda replaceEach z Apache Commons Lang może się przydać w zależności od twoich konkretnych potrzeb. Możesz go łatwo użyć do zastąpienia symboli zastępczych według nazwy za pomocą tego pojedynczego wywołania metody:
Biorąc pod uwagę pewien tekst wejściowy, spowoduje to zastąpienie wszystkich wystąpień symboli zastępczych w pierwszej tablicy ciągów odpowiednimi wartościami w drugiej.
źródło
Możesz mieć coś takiego w klasie pomocniczej napisów
źródło
Moja odpowiedź brzmi:
a) użyj StringBuilder, jeśli to możliwe
b) zachowaj (w dowolnej postaci: liczba całkowita jest najlepszym, konkretnym znakiem, np. makro dolara itp.) pozycję "symbolu zastępczego", a następnie użyj
StringBuilder.insert()
(kilka wersji argumentów).Korzystanie z zewnętrznych bibliotek wydaje się przesadą i uważam, że znacznie obniża wydajność, gdy StringBuilder jest wewnętrznie konwertowany na String.
źródło
Na podstawie odpowiedzi stworzyłem
MapBuilder
klasę:następnie stworzyłem klasę
StringFormat
do formatowania String:którego możesz użyć w ten sposób:
źródło
Stworzyłem również klasę util / helper (przy użyciu jdk 8), która może formatować ciąg znaków i zastępować wystąpienia zmiennych.
W tym celu użyłem metody „appendReplacement” dopasowujących, która wykonuje wszystkie podstawienia i wykonuje pętlę tylko na odpowiednich częściach ciągu formatu.
Klasa pomocnicza nie jest obecnie dobrze udokumentowana w javadoc. Zmienię to w przyszłości;) Tak czy inaczej skomentowałem najważniejsze kwestie (mam nadzieję).
Możesz utworzyć instancję klasy dla określonej mapy z wartościami (lub prefiksem sufiksu lub noKeyFunction), takimi jak:
Co więcej, możesz zdefiniować, co się stanie, jeśli brakuje klucza w wartościach Map (działa w obie strony, np. Zła nazwa zmiennej w ciągu formatującym lub brakujący klucz w Map). Domyślnym zachowaniem jest wyrzucony niezaznaczony wyjątek (niezaznaczony, ponieważ używam domyślnej funkcji jdk8, która nie obsługuje sprawdzonych wyjątków), na przykład:
Możesz zdefiniować niestandardowe zachowanie w wywołaniu konstruktora, takie jak:
lub deleguj go z powrotem do domyślnego zachowania bez klucza:
Dla lepszej obsługi istnieją również statyczne reprezentacje metod, takie jak:
źródło
W tej chwili w Javie nie ma nic wbudowanego. Proponuję napisać własną implementację. Preferuję prosty, płynny interfejs konstruktora zamiast tworzenia mapy i przekazywania jej do funkcji - w rezultacie otrzymujesz ładny, ciągły fragment kodu, na przykład:
Oto prosta implementacja:
źródło
Wypróbuj Freemarker , bibliotekę szablonów.
źródło
Najprostszym sposobem byłoby https://dzone.com/articles/java-string-format-examples String.format (inputString, [listOfParams]). Symbole zastępcze w ciągu można definiować według kolejności. Aby uzyskać więcej informacji, sprawdź podany link.
źródło
Powinieneś zajrzeć do oficjalnej biblioteki ICU4J . Zapewnia MessageFormat klasę podobną do tej, dostępnej z JDK ale to dawnych podpór nazwanych zastępcze.
W przeciwieństwie do innych rozwiązań przedstawionych na tej stronie. ICU4j jest częścią projektu ICU który jest obsługiwany przez IBM i regularnie aktualizowany. Ponadto obsługuje zaawansowane przypadki użycia, takie jak liczba mnoga i wiele innych.
Oto przykład kodu:
źródło
Istnieje wtyczka Java do używania interpolacji ciągów w Javie (jak w Kotlin, JavaScript). Wspiera obsługę Javy, 8, 9, 10, 11 ... https://github.com/antkorwin/better-strings
Używanie zmiennych w literałach łańcuchowych:
Korzystanie z wyrażeń:
Korzystanie z funkcji:
Aby uzyskać więcej informacji, przeczytaj projekt README.
źródło