Java 정규식(Regular Expression)에서 서브 표현식이자 메타 문자인 "\B"는 비단어 경계(non-word boundary), 즉 단어 경계가 아닌 위치와 일치합니다.
쉽게 설명하면, \b가 단어 문자와 비단어 문자 사이의 '경계'를 찾는 것과 달리, \B는 그 반대로 단어의 내부처럼 경계에 해당하지 않는 위치를 매칭합니다. 예를 들어 "because"라는 단어 안의 "cause"처럼 앞뒤가 모두 단어 문자로 둘러싸인 위치를 찾을 때 유용합니다.
예제 1
다음 예제는 정규식 "\Bcause"를 사용하여 입력 문자열에서 단어 경계가 아닌 위치에 나타나는 "cause"의 등장 횟수를 세는 프로그램입니다. Pattern 클래스로 정규식을 컴파일하고, Matcher 객체로 문자열을 검사합니다.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
public static void main( String args[] ) {
String regex = "\\Bcause";
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string: ");
String input = sc.nextLine();
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
int count = 0;
while(m.find()) {
count ++;
}
System.out.println("Number of matches: "+count);
}
}실행 결과
입력 문자열에 "because"가 세 번 포함되어 있으며, 각 "because" 내부의 "cause"는 단어 경계가 아닌 위치에 있으므로 총 3번 매칭됩니다.
Enter a string: A sentence doesn't end with because because, because is a conjunction Number of matches: 3
예제 2
이번에는 메타 문자 "\B"만 단독으로 사용하여 입력 문자열 전체에서 비단어 경계의 개수를 세어 보겠습니다. 각 단어 길이가 n일 때 내부 경계는 n-1개씩 발생하므로, 공백으로 구분된 여러 단어의 내부 위치들이 모두 카운트됩니다.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Example {
public static void main( String args[] ) {
System.out.println("Enter input string: ");
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String regex = "\\B";
//Compiling the regular expression
Pattern pattern = Pattern.compile(regex);
//Retrieving the matcher object
Matcher matcher = pattern.matcher(input);
int count =0;
System.out.println("Non-word boundaries: ");
while(matcher.find()) {
count ++;
}
System.out.println(count);
}
}실행 결과
입력된 문장의 각 단어(Hello, how, are, you, welcome, to, Tutorialspoint) 내부의 비단어 경계가 합산되어 총 30개로 출력됩니다.
Enter input string: Hello how are you welcome to Tutorialspoint Non-word boundaries: 30