문자열을 분할하고 구분 기호를 유지하는 방법
여러 개의 딜리미터로 구분된 여러 줄의 문자열이 있습니다.
(Text1)(DelimiterA)(Text2)(DelimiterC)(Text3)(DelimiterB)(Text4)
수 요.String.split
그러나 딜리미터 regex와 일치하는 실제 문자열을 얻을 수 없는 것 같습니다.
즉, 다음과 같은 것을 얻을 수 있는 것은 다음과 같습니다.
Text1
Text2
Text3
Text4
이게 내가 원하는 거야
Text1
DelimiterA
Text2
DelimiterC
Text3
DelimiterB
Text4
딜리미터 regex를 사용하여 문자열을 분할하고 딜리미터를 유지하는 JDK 방법이 있습니까?
정규식의 기능인 룩어헤드 및 룩백을 사용할 수 있습니다.
System.out.println(Arrays.toString("a;b;c;d".split("(?<=;)")));
System.out.println(Arrays.toString("a;b;c;d".split("(?=;)")));
System.out.println(Arrays.toString("a;b;c;d".split("((?<=;)|(?=;))")));
다음과 같은 이점을 얻을 수 있습니다.
[a;, b;, c;, d]
[a, ;b, ;c, ;d]
[a, ;, b, ;, c, ;, d]
마지막은 네가 원하는 거야
((?<=;)|(?=;))
.;
그 후에;
.
편집: 가독성에 대한 Fabian Steeg의 코멘트는 유효합니다.정규 표현에서는 가독성이 항상 문제가 됩니다.정규식을 읽기 쉽게 만들기 위해 수행하는 작업 중 하나는 변수를 만드는 것입니다. 변수의 이름은 정규식이 수행하는 작업을 나타냅니다.플레이스 홀더를 배치할 수도 있습니다(예:%1$s
를 사용합니다.String.format
플레이스 홀더를 사용할 실제 문자열로 바꿉니다.하다
static public final String WITH_DELIMITER = "((?<=%1$s)|(?=%1$s))";
public void someMethod() {
final String[] aEach = "a;b;c;d".split(String.format(WITH_DELIMITER, ";"));
...
}
룩어라운드를 사용하여 제로 폭 일치로 분할하는 경우.다음은 몇 가지 예입니다.
public class SplitNDump {
static void dump(String[] arr) {
for (String s : arr) {
System.out.format("[%s]", s);
}
System.out.println();
}
public static void main(String[] args) {
dump("1,234,567,890".split(","));
// "[1][234][567][890]"
dump("1,234,567,890".split("(?=,)"));
// "[1][,234][,567][,890]"
dump("1,234,567,890".split("(?<=,)"));
// "[1,][234,][567,][890]"
dump("1,234,567,890".split("(?<=,)|(?=,)"));
// "[1][,][234][,][567][,][890]"
dump(":a:bb::c:".split("(?=:)|(?<=:)"));
// "[][:][a][:][bb][:][:][c][:]"
dump(":a:bb::c:".split("(?=(?!^):)|(?<=:)"));
// "[:][a][:][bb][:][:][c][:]"
dump(":::a::::b b::c:".split("(?=(?!^):)(?<!:)|(?!:)(?<=:)"));
// "[:::][a][::::][b b][::][c][:]"
dump("a,bb:::c d..e".split("(?!^)\\b"));
// "[a][,][bb][:::][c][ ][d][..][e]"
dump("ArrayIndexOutOfBoundsException".split("(?<=[a-z])(?=[A-Z])"));
// "[Array][Index][Out][Of][Bounds][Exception]"
dump("1234567890".split("(?<=\\G.{4})"));
// "[1234][5678][90]"
// Split at the end of each run of letter
dump("Boooyaaaah! Yippieeee!!".split("(?<=(?=(.)\\1(?!\\1))..)"));
// "[Booo][yaaaa][h! Yipp][ieeee][!!]"
}
}
네, 마지막 패턴에서 세 번 강조된 주장입니다.
관련 질문
- 자바 스플릿이 내 캐릭터를 잡아먹고 있어.
- String split에서 제로폭 매칭 regex를 사용할 수 있습니까?
- Java에서 Camel Case를 사람이 읽을 수 있는 이름으로 변환하려면 어떻게 해야 합니까?
- 뒷면 참조
「 」를 참조해 주세요.
regex를 수반하지 않는 매우 순진한 솔루션은 다음과 같은 행에 따라 딜리미터에 문자열 치환을 실행하는 것입니다(딜리미터는 콤마로 가정).
string.replace(FullString, "," , "~,~")
여기서 tilda(~)를 적절한 고유 구분 기호로 대체할 수 있습니다.
그리고 새 구분 기호를 분할하면 원하는 결과를 얻을 수 있을 것입니다.
import java.util.regex.*;
import java.util.LinkedList;
public class Splitter {
private static final Pattern DEFAULT_PATTERN = Pattern.compile("\\s+");
private Pattern pattern;
private boolean keep_delimiters;
public Splitter(Pattern pattern, boolean keep_delimiters) {
this.pattern = pattern;
this.keep_delimiters = keep_delimiters;
}
public Splitter(String pattern, boolean keep_delimiters) {
this(Pattern.compile(pattern==null?"":pattern), keep_delimiters);
}
public Splitter(Pattern pattern) { this(pattern, true); }
public Splitter(String pattern) { this(pattern, true); }
public Splitter(boolean keep_delimiters) { this(DEFAULT_PATTERN, keep_delimiters); }
public Splitter() { this(DEFAULT_PATTERN); }
public String[] split(String text) {
if (text == null) {
text = "";
}
int last_match = 0;
LinkedList<String> splitted = new LinkedList<String>();
Matcher m = this.pattern.matcher(text);
while (m.find()) {
splitted.add(text.substring(last_match,m.start()));
if (this.keep_delimiters) {
splitted.add(m.group());
}
last_match = m.end();
}
splitted.add(text.substring(last_match));
return splitted.toArray(new String[splitted.size()]);
}
public static void main(String[] argv) {
if (argv.length != 2) {
System.err.println("Syntax: java Splitter <pattern> <text>");
return;
}
Pattern pattern = null;
try {
pattern = Pattern.compile(argv[0]);
}
catch (PatternSyntaxException e) {
System.err.println(e);
return;
}
Splitter splitter = new Splitter(pattern);
String text = argv[1];
int counter = 1;
for (String part : splitter.split(text)) {
System.out.printf("Part %d: \"%s\"\n", counter++, part);
}
}
}
/*
Example:
> java Splitter "\W+" "Hello World!"
Part 1: "Hello"
Part 2: " "
Part 3: "World"
Part 4: "!"
Part 5: ""
*/
앞뒤에 빈 요소가 있는 다른 방법은 별로 좋아하지 않습니다.일반적으로 딜리미터는 문자열의 처음이나 끝에 없기 때문에 대부분의 경우 정상적인 어레이 슬롯을 두 개 낭비하게 됩니다.
편집: 고정 제한 케이스.테스트 케이스에 관한 코멘트 첨부 출처는, http://snippets.dzone.com/posts/show/6453 를 참조해 주세요.
세 번째 urgument를 true로 넘기세요.딜리미터도 반환됩니다.
StringTokenizer(String str, String delimiters, true);
매우 오래된 질문이라는 것을 알고 있으며, 답변도 받아들여지고 있습니다.하지만 여전히 나는 원래의 질문에 매우 간단한 답변을 제출하고 싶다.다음 코드를 고려하십시오.
String str = "Hello-World:How\nAre You&doing";
inputs = str.split("(?!^)\\b");
for (int i=0; i<inputs.length; i++) {
System.out.println("a[" + i + "] = \"" + inputs[i] + '"');
}
출력:
a[0] = "Hello"
a[1] = "-"
a[2] = "World"
a[3] = ":"
a[4] = "How"
a[5] = "
"
a[6] = "Are"
a[7] = " "
a[8] = "You"
a[9] = "&"
a[10] = "doing"
경계라는 하고 있어요.\b
텍스트 시작일 때를 제외하고 단어를 구분합니다.
제가 늦게 도착했는데, 원래 질문으로 돌아가서, 그냥 룩어라운드를 사용하면 어떨까요?
Pattern p = Pattern.compile("(?<=\\w)(?=\\W)|(?<=\\W)(?=\\w)");
System.out.println(Arrays.toString(p.split("'ab','cd','eg'")));
System.out.println(Arrays.toString(p.split("boo:and:foo")));
출력:
[', ab, ',', cd, ',', eg, ']
[boo, :, and, :, foo]
EDIT: 위에 보이는 것은 해당 코드를 실행하면 명령줄에 표시되는 내용입니다만, 조금 혼란스럽다는 것을 알 수 있습니다.되었는지 알 수Arrays.toString()
SO의 구문 강조 표시도 도움이 되지 않습니다.이러한 어레이를 소스코드로 선언한 것은 다음과 같습니다.
{ "'", "ab", "','", "cd", "','", "eg", "'" }
{ "boo", ":", "and", ":", "foo" }
그게 더 읽기 쉬웠으면 좋겠어요.알려줘서 고마워, @finnw.
위의 답변을 봤는데 솔직히 만족스러운 답변이 하나도 없네요.기본적으로 Perl 스플릿 기능을 모방해야 합니다.왜 Java가 이를 허용하지 않고 join() 메서드를 사용하는지 이해할 수 없지만, 저는 이 문제를 언급하고 싶습니다.이런 거 수업도 필요없잖아그냥 함수일 뿐이야.다음 샘플 프로그램을 실행합니다.
이전 답변 중 일부는 과도한 null-checking을 포함하고 있으며, 최근 여기에 질문에 대한 답변을 작성했습니다.
https://stackoverflow.com/users/18393/cletus
어쨌든, 코드는:
public class Split {
public static List<String> split(String s, String pattern) {
assert s != null;
assert pattern != null;
return split(s, Pattern.compile(pattern));
}
public static List<String> split(String s, Pattern pattern) {
assert s != null;
assert pattern != null;
Matcher m = pattern.matcher(s);
List<String> ret = new ArrayList<String>();
int start = 0;
while (m.find()) {
ret.add(s.substring(start, m.start()));
ret.add(m.group());
start = m.end();
}
ret.add(start >= s.length() ? "" : s.substring(start));
return ret;
}
private static void testSplit(String s, String pattern) {
System.out.printf("Splitting '%s' with pattern '%s'%n", s, pattern);
List<String> tokens = split(s, pattern);
System.out.printf("Found %d matches%n", tokens.size());
int i = 0;
for (String token : tokens) {
System.out.printf(" %d/%d: '%s'%n", ++i, tokens.size(), token);
}
System.out.println();
}
public static void main(String args[]) {
testSplit("abcdefghij", "z"); // "abcdefghij"
testSplit("abcdefghij", "f"); // "abcde", "f", "ghi"
testSplit("abcdefghij", "j"); // "abcdefghi", "j", ""
testSplit("abcdefghij", "a"); // "", "a", "bcdefghij"
testSplit("abcdefghij", "[bdfh]"); // "a", "b", "c", "d", "e", "f", "g", "h", "ij"
}
}
StringTokenizer는 Enumerable입니다.
그러나 이 명령어는 더 이상 사용되지 않으며 지루한 String[]을 반환하는 String.split으로 대체됩니다(구분자는 포함되지 않습니다).
그래서 StringTokenizerEx를 구현했습니다.StringTokenizerEx는 반복 가능하며 문자열을 분할하려면 진정한 regexp가 필요합니다.
는 딜리미터를 형성하기합니다.true regexp는 ' 시퀀스'가 아닙니다.
는 '하고 '는 세 구분 기호로에 두 빈 있습니다: 'o'는 'o'로 구분됩니다.
[o], '', [o], '', [o]
그러나 regexp o+는 "aooob"을 분할할 때 예상된 결과를 반환합니다.
[], 'a', [ooo], 'b', []
이 StringTokenizer를 사용하려면예:
final StringTokenizerEx aStringTokenizerEx = new StringTokenizerEx("boo:and:foo", "o+");
final String firstDelimiter = aStringTokenizerEx.getDelimiter();
for(String aString: aStringTokenizerEx )
{
// uses the split String detected and memorized in 'aString'
final nextDelimiter = aStringTokenizerEx.getDelimiter();
}
이 클래스의 코드는 DZone 스니펫에서 사용할 수 있습니다.
코드 챌린지 응답(테스트 케이스가 포함된 자기포함 클래스 1개)의 경우와 마찬가지로 복사 붙여넣기('src/test' 디렉토리)를 실행합니다.main() 메서드는 다양한 사용법을 보여줍니다.
주의: (2009년 후반 편집)
기사 Final Thoughts: Java Puzzler: Spliting Hairs는 의 기괴한 행동을 설명하는 좋은 일을 한다.String.split()
.
조쉬 블로흐
아, 아, 아, 아, 아, 아, 아, 아, 아.FWIW Perl f fw 。
Mike "madbot" McCloskey 。Mike는 Java의 정규식이 거의 모든 30K Perl 정규식 테스트를 통과하고 더 빠르게 실행되었음을 확인했습니다.
Google 공통 라이브러리 Guava에는 다음과 같은 스플리터도 포함되어 있습니다.
- 사용하기 쉽다
- Google(고객이 아닌)에 의해 유지보수됩니다.
그래서 확인해 볼 가치가 있을 것이다.초기 개략 문서(pdf):
JDK의 특징은 다음과 같습니다.
String[] pieces = "foo.bar".split("\\.");
원하는 대로 사용할 수 있습니다. - 정규 표현 - 결과 배열 - 빈 조각을 처리하는 방법
Mini-puzler: ",a,b",.split("") 반환...
(a) "", "a", "", "b", ""
(b) null, "a", null, "b", null
(c) "a", null, "b"
(d) "a", "b"
(e) None of the above
답변: (e) 위의 내용은 없습니다.
",a,,b,".split(",")
returns
"", "a", "", "b"
후행 빈칸만 건너뜁니다! (건너뛰기를 방지하기 위한 해결 방법을 알 수 있는 사람?재밌어요...)
어떤 경우에도 스플리터는 유연성이 뛰어납니다.기본 동작은 단순합니다.
Splitter.on(',').split(" foo, ,bar, quux,")
--> [" foo", " ", "bar", " quux", ""]
추가 기능을 원하시면 요청하세요!
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split(" foo, ,bar, quux,")
--> ["foo", "bar", "quux"]
구성 메서드의 순서는 중요하지 않습니다. 분할하는 동안 트리밍은 빈 공간을 확인하기 전에 수행됩니다.
여기에서는, 다음과 같은 심플한 클린 실장을 실시합니다.Pattern#split
또, 길이 패턴도 다양하기 때문에, 뒤에서 보면 서포트할 수 없고, 사용하기 편리합니다.이는 @cletus가 제공하는 솔루션과 유사합니다.
public static String[] split(CharSequence input, String pattern) {
return split(input, Pattern.compile(pattern));
}
public static String[] split(CharSequence input, Pattern pattern) {
Matcher matcher = pattern.matcher(input);
int start = 0;
List<String> result = new ArrayList<>();
while (matcher.find()) {
result.add(input.subSequence(start, matcher.start()).toString());
result.add(matcher.group());
start = matcher.end();
}
if (start != input.length()) result.add(input.subSequence(start, input.length()).toString());
return result.toArray(new String[0]);
}
.Pattern#split
가가왜 왜? ???에 i i가 에 들지 않는다if
이지만 일관성을 하기 위해 합니다.Pattern#split
그렇지 않으면 무조건 추가되므로 입력 문자열이 패턴으로 끝나는 경우 결과의 마지막 요소로 빈 문자열이 됩니다.
String [ ]로 변환하여 String [ ]와의합니다.Pattern#split
, , , 을합니다.new String[0]
new String[result.size()]
이유는 여기를 참조해 주세요.
테스트 내용은 다음과 같습니다.
@Test
public void splitsVariableLengthPattern() {
String[] result = Split.split("/foo/$bar/bas", "\\$\\w+");
Assert.assertArrayEquals(new String[] { "/foo/", "$bar", "/bas" }, result);
}
@Test
public void splitsEndingWithPattern() {
String[] result = Split.split("/foo/$bar", "\\$\\w+");
Assert.assertArrayEquals(new String[] { "/foo/", "$bar" }, result);
}
@Test
public void splitsStartingWithPattern() {
String[] result = Split.split("$foo/bar", "\\$\\w+");
Assert.assertArrayEquals(new String[] { "", "$foo", "/bar" }, result);
}
@Test
public void splitsNoMatchesPattern() {
String[] result = Split.split("/foo/bar", "\\$\\w+");
Assert.assertArrayEquals(new String[] { "/foo/bar" }, result);
}
작업 버전도 올리겠습니다(첫 번째는 Markus와 매우 비슷합니다).
public static String[] splitIncludeDelimeter(String regex, String text){
List<String> list = new LinkedList<>();
Matcher matcher = Pattern.compile(regex).matcher(text);
int now, old = 0;
while(matcher.find()){
now = matcher.end();
list.add(text.substring(old, now));
old = now;
}
if(list.size() == 0)
return new String[]{text};
//adding rest of a text as last element
String finalElement = text.substring(old);
list.add(finalElement);
return list.toArray(new String[list.size()]);
}
다음은 두 번째 솔루션으로, 첫 번째 솔루션보다 약 50% 더 빠릅니다.
public static String[] splitIncludeDelimeter2(String regex, String text){
List<String> list = new LinkedList<>();
Matcher matcher = Pattern.compile(regex).matcher(text);
StringBuffer stringBuffer = new StringBuffer();
while(matcher.find()){
matcher.appendReplacement(stringBuffer, matcher.group());
list.add(stringBuffer.toString());
stringBuffer.setLength(0); //clear buffer
}
matcher.appendTail(stringBuffer); ///dodajemy reszte ciagu
list.add(stringBuffer.toString());
return list.toArray(new String[list.size()]);
}
regex를 사용하는 다른 후보 솔루션.토큰 순서를 유지하고 동일한 유형의 여러 토큰을 한 행에 올바르게 일치시킵니다.단점은 정규식이 좀 심하다는 것이다.
package javaapplication2;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JavaApplication2 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String num = "58.5+variable-+98*78/96+a/78.7-3443*12-3";
// Terrifying regex:
// (a)|(b)|(c) match a or b or c
// where
// (a) is one or more digits optionally followed by a decimal point
// followed by one or more digits: (\d+(\.\d+)?)
// (b) is one of the set + * / - occurring once: ([+*/-])
// (c) is a sequence of one or more lowercase latin letter: ([a-z]+)
Pattern tokenPattern = Pattern.compile("(\\d+(\\.\\d+)?)|([+*/-])|([a-z]+)");
Matcher tokenMatcher = tokenPattern.matcher(num);
List<String> tokens = new ArrayList<>();
while (!tokenMatcher.hitEnd()) {
if (tokenMatcher.find()) {
tokens.add(tokenMatcher.group());
} else {
// report error
break;
}
}
System.out.println(tokens);
}
}
샘플 출력:
[58.5, +, variable, -, +, 98, *, 78, /, 96, +, a, /, 78.7, -, 3443, *, 12, -, 3]
Java API에서 이 기능을 하는 기존 함수는 알 수 없지만(존재하지 않는 것은 아니지만) 저만의 구현이 있습니다(하나 이상의 딜리미터가 단일 토큰으로 반환됩니다. 각 딜리미터를 별도의 토큰으로 반환하려면 약간의 적응이 필요합니다).
static String[] splitWithDelimiters(String s) {
if (s == null || s.length() == 0) {
return new String[0];
}
LinkedList<String> result = new LinkedList<String>();
StringBuilder sb = null;
boolean wasLetterOrDigit = !Character.isLetterOrDigit(s.charAt(0));
for (char c : s.toCharArray()) {
if (Character.isLetterOrDigit(c) ^ wasLetterOrDigit) {
if (sb != null) {
result.add(sb.toString());
}
sb = new StringBuilder();
wasLetterOrDigit = !wasLetterOrDigit;
}
sb.append(c);
}
result.add(sb.toString());
return result.toArray(new String[0]);
}
Pattern과 Matcher를 사용하는 것이 좋습니다.이것은 거의 확실히 당신이 원하는 것을 달성할 수 있습니다.정규 표현은 String.split에서 사용하는 것보다 다소 복잡해야 합니다.
될 것 요.String#split
단, , 을 사용할 수.StringTokenizer
이 딜리미터를할 수는 , 할 수 .이 경우, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」라고 합니다.
new StringTokenizer("Hello, world. Hi!", ",.!", true); // true for returnDelims
여유가 있는 경우 Java의 replace(CharSequence target, CharSequence replacement) 메서드를 사용하고 분할할 다른 딜리미터를 입력합니다.예:문자열 "boo:and:foo"를 분할하고 문자열의 오른쪽 끝에 ':'를 둡니다.
String str = "boo:and:foo";
str = str.replace(":","newdelimiter:");
String[] tokens = str.split("newdelimiter");
중요사항:이 기능은 String에 더 이상의 "새로운 구분자"가 없는 경우에만 작동합니다.따라서 일반적인 해결책은 아닙니다.단, Char Sequence가 String에 표시되지 않는 것을 확인할 수 있는 경우 이는 매우 간단한 해결책입니다.
빠른 답변: \b와 같은 비물리적 경계를 사용하여 분할합니다.(PHP와 JS에서 사용) 동작하는지 시험해 보겠습니다.
그럴 수도 있고, 일이지만, 너무 많이 쪼개질 수도 있어요.실제로는 분할할 문자열과 필요한 결과에 따라 달라집니다.자세한 내용을 알려주시면 더 잘 도와드리겠습니다.
또 다른 방법은 사용자가 분할하여 딜리미터를 캡처하고(변수인 경우), 나중에 결과에 추가하는 것입니다.
간단한 테스트:
String str = "'ab','cd','eg'";
String[] stra = str.split("\\b");
for (String s : stra) System.out.print(s + "|");
System.out.println();
결과:
'|ab|','|cd|','|eg|'|
조금 과한... :-)
일치하는 패턴을 목록에 포함하도록 조정된 패턴.split()
추가된
// add match to the list
matchList.add(input.subSequence(start, end).toString());
풀 소스
public static String[] inclusiveSplit(String input, String re, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList<String> matchList = new ArrayList<String>();
Pattern pattern = Pattern.compile(re);
Matcher m = pattern.matcher(input);
// Add segments before each match found
while (m.find()) {
int end = m.end();
if (!matchLimited || matchList.size() < limit - 1) {
int start = m.start();
String match = input.subSequence(index, start).toString();
matchList.add(match);
// add match to the list
matchList.add(input.subSequence(start, end).toString());
index = end;
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index, input.length())
.toString();
matchList.add(match);
index = end;
}
}
// If no match was found, return this
if (index == 0)
return new String[] { input.toString() };
// Add remaining segment
if (!matchLimited || matchList.size() < limit)
matchList.add(input.subSequence(index, input.length()).toString());
// Construct result
int resultSize = matchList.size();
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize - 1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return matchList.subList(0, resultSize).toArray(result);
}
여기 위의 코드 중 일부를 기반으로 한 그루비 버전이 있습니다. 도움이 될 수 있습니다.어쨌든 짧아요.조건부로 머리와 꼬리를 포함합니다(공백이 아닌 경우).마지막 부분은 데모/테스트 케이스입니다.
List splitWithTokens(str, pat) {
def tokens=[]
def lastMatch=0
def m = str=~pat
while (m.find()) {
if (m.start() > 0) tokens << str[lastMatch..<m.start()]
tokens << m.group()
lastMatch=m.end()
}
if (lastMatch < str.length()) tokens << str[lastMatch..<str.length()]
tokens
}
[['<html><head><title>this is the title</title></head>',/<[^>]+>/],
['before<html><head><title>this is the title</title></head>after',/<[^>]+>/]
].each {
println splitWithTokens(*it)
}
그럼에도 불구하고 매우 순진하고 비효율적인 해결책입니다.문자열에서 두 번 분할을 사용한 후 두 개의 어레이를 연결합니다.
String temp[]=str.split("\\W");
String temp2[]=str.split("\\w||\\s");
int i=0;
for(String string:temp)
System.out.println(string);
String temp3[]=new String[temp.length-1];
for(String string:temp2)
{
System.out.println(string);
if((string.equals("")!=true)&&(string.equals("\\s")!=true))
{
temp3[i]=string;
i++;
}
// System.out.println(temp.length);
// System.out.println(temp2.length);
}
System.out.println(temp3.length);
String[] temp4=new String[temp.length+temp3.length];
int j=0;
for(i=0;i<temp.length;i++)
{
temp4[j]=temp[i];
j=j+2;
}
j=1;
for(i=0;i<temp3.length;i++)
{
temp4[j]=temp3[i];
j+=2;
}
for(String s:temp4)
System.out.println(s);
String expression = "((A+B)*C-D)*E";
expression = expression.replaceAll("\\+", "~+~");
expression = expression.replaceAll("\\*", "~*~");
expression = expression.replaceAll("-", "~-~");
expression = expression.replaceAll("/+", "~/~");
expression = expression.replaceAll("\\(", "~(~"); //also you can use [(] instead of \\(
expression = expression.replaceAll("\\)", "~)~"); //also you can use [)] instead of \\)
expression = expression.replaceAll("~~", "~");
if(expression.startsWith("~")) {
expression = expression.substring(1);
}
String[] expressionArray = expression.split("~");
System.out.println(Arrays.toString(expressionArray));
이 질문의 하위 항목 중 하나는 "선행 구분 기호" 질문과 관련이 있습니다. 토큰과 구분 기호 중 어느 것으로 시작할지 알아야 합니다.물론 선행 구분선을 폐기해야 한다고 가정할 수 있지만 이는 부당한 가정으로 보입니다.후행 구분 기호가 있는지 여부도 확인할 수 있습니다.이에 따라 2개의 부울 플래그가 설정됩니다.
Groovy로 작성되어 있지만 Java 버전은 매우 명확합니다.
String tokenRegex = /[\p{L}\p{N}]+/ // a String in Groovy, Unicode alphanumeric
def finder = phraseForTokenising =~ tokenRegex
// NB in Groovy the variable 'finder' is then of class java.util.regex.Matcher
def finderIt = finder.iterator() // extra method added to Matcher by Groovy magic
int start = 0
boolean leadingDelim, trailingDelim
def combinedTokensAndDelims = [] // create an array in Groovy
while( finderIt.hasNext() )
{
def token = finderIt.next()
int finderStart = finder.start()
String delim = phraseForTokenising[ start .. finderStart - 1 ]
// Groovy: above gets slice of String/array
if( start == 0 ) leadingDelim = finderStart != 0
if( start > 0 || leadingDelim ) combinedTokensAndDelims << delim
combinedTokensAndDelims << token // add element to end of array
start = finder.end()
}
// start == 0 indicates no tokens found
if( start > 0 ) {
// finish by seeing whether there is a trailing delim
trailingDelim = start < phraseForTokenising.length()
if( trailingDelim ) combinedTokensAndDelims << phraseForTokenising[ start .. -1 ]
println( "leading delim? $leadingDelim, trailing delim? $trailingDelim, combined array:\n $combinedTokensAndDelims" )
}
는, 스플릿 해 주세요.이 있습니다..split()
★★★★★★ 。
다음의 예를 참조해 주세요.
public class SplitExample {
public static void main(String[] args) {
String str = "Javathomettt";
System.out.println("method 1");
System.out.println("Returning words:");
String[] arr = str.split("t", 40);
for (String w : arr) {
System.out.println(w+"t");
}
System.out.println("Split array length: "+arr.length);
System.out.println("method 2");
System.out.println(str.replaceAll("t", "\n"+"t"));
}
자바에 대해서는 잘 모르지만, 만약 그것을 할 수 있는 Split 메서드를 찾을 수 없다면, 직접 만들어 보는 것이 좋습니다.
string[] mySplit(string s,string delimiter)
{
string[] result = s.Split(delimiter);
for(int i=0;i<result.Length-1;i++)
{
result[i] += delimiter; //this one would add the delimiter to each items end except the last item,
//you can modify it however you want
}
}
string[] res = mySplit(myString,myDelimiter);
너무 우아하진 않지만, 괜찮을 거예요.
언급URL : https://stackoverflow.com/questions/2206378/how-to-split-a-string-but-also-keep-the-delimiters
'source' 카테고리의 다른 글
Eclipse의 Import된 Maven 프로젝트가 기본적으로 Java 1.6 대신 Java 1.5를 사용하는 이유는 무엇이며, 어떻게 하면 그렇지 않은지 확인할 수 있습니까? (0) | 2022.07.31 |
---|---|
조건부 부정 대신 abs() 또는 fabs()를 사용하는 이유는 무엇입니까? (0) | 2022.07.31 |
Vue.js 데이터 테이블이 첫 번째 열에 데이터만 표시됨 (0) | 2022.07.31 |
vuex와 socketio를 사용하여 실시간 크러드를 만드는 방법 (0) | 2022.07.31 |
java.net 를 참조해 주세요.Connect Exception:연결이 거부되었습니다. (0) | 2022.07.31 |