Java中按指定模式为字符串插入空格的实现问题
First, let's break down why your original regex isn't working. Your pattern (-?\\d+|\\D+)(?=[+\\-*/]+) tries to match either a number or non-digit characters followed by operators, then adds a space. But this ends up splitting the operator substring into individual characters (like turning "+++" into "+ + +") instead of keeping the entire operator sequence intact. Also, it doesn't handle cases where a "-" is part of the subsequent number (like in "5 ++ -5") correctly.
Here's a reliable approach to get the desired output:
Step-by-Step Solution
- Remove existing spaces: First, strip all whitespace to simplify processing, since existing spaces can interfere with matching the operator substring.
- Add spaces around operator sequences: Insert a space between the end of part1 and the start of the operator substring, then another between the end of the operator substring and the start of part2.
- Normalize spaces: Ensure there are no multiple spaces and trim any leading/trailing whitespace.
Code Implementation
public class OperatorSpaceFormatter { public static String formatString(String input) { // Step 1: Remove all existing spaces String noSpaces = input.replaceAll("\\s+", ""); // Step 2: Add space between part1 and operators String spaceAfterPart1 = noSpaces.replaceAll("([^+\\-*/])([+\\-*/])", "$1 $2"); // Step 3: Add space between operators and part2 String spaceBeforePart2 = spaceAfterPart1.replaceAll("([+\\-*/])([^+\\-*/])", "$1 $2"); // Step 4: Normalize spaces (trim and replace multiple spaces with single) return spaceBeforePart2.replaceAll("\\s+", " ").trim(); } public static void main(String[] args) { // Test cases System.out.println(formatString("-5+++5")); // Output: -5 +++ 5 System.out.println(formatString("5 ++ -5")); // Output: 5 ++ -5 System.out.println(formatString("ABC */ ZXC")); // Output: ABC */ ZXC System.out.println(formatString("-XY** XX")); // Output: -XY ** XX } }
How It Works
- Removing spaces:
replaceAll("\\s+", "")eliminates any existing whitespace, so we're working with a clean string without gaps. - Space after part1: The regex
([^+\\-*/])([+\\-*/])matches a non-operator character followed by an operator, then replaces it with the non-operator plus a space plus the operator. This separates part1 from the operator sequence. - Space before part2: The regex
([+\\-*/])([^+\\-*/])matches an operator followed by a non-operator character, replacing it with the operator plus a space plus the non-operator. This separates the operator sequence from part2. - Normalizing spaces: Ensures consistent single spaces and no extra whitespace at the edges.
Alternative Combined Regex
You can combine the space insertion steps into a single line using lookbehind and lookahead assertions if you prefer:
String formatted = input.replaceAll("\\s+", "") .replaceAll("(?<=[^+\\-*/])([+\\-*/])", " $1") .replaceAll("([+\\-*/])(?=[^+\\-*/])", "$1 ") .replaceAll("\\s+", " ").trim();
This achieves the same result in a more concise way, using lookbehind ((?<=...)) to check for a preceding non-operator and lookahead ((?=...)) to check for a following non-operator.
内容的提问来源于stack exchange,提问作者PRD

