正则表达式只允许Java字符串中的一个标点字符

时间:2016-07-22 15:05:37

标签: java regex

我需要解析原始数据并允许包含字母表且只包含一个标点字符的字符串。

这是我到目前为止所做的:

public class ProcessRawData {

public static void main(String[] args) {
    String myData = "Australia India# America@!";
    ProcessRawData data = new ProcessRawData();
    data.process(myData);

}

public void process(String rawData) {
    String[] splitData = rawData.split(" ");
    for (String s : splitData) {
        System.out.println("My Data Elements: " + s);
        Pattern pattern = Pattern.compile("^[\\p{Alpha}\\p{Punct}]*$");
        Matcher matcher = pattern.matcher(s);
        if (matcher.matches()) {
            System.out.println("Allowed");
        } else {
            System.out.println("Not allowed");
        }
    }
}

}

它打印在下面,

My Data Elements: Australia
Allowed
My Data Elements: India#
Allowed
My Data Elements: America@!
Allowed

预计它不应该打印 America @!,因为它包含多个标点字符。

我想我可能需要使用量词,但不知道在哪里放置它们以便它只允许一个标点字符?

有人可以帮忙吗?

5 个答案:

答案 0 :(得分:2)

您应该在循环外编译Pattern

使用matches()时,不需要^$,因为它无论如何都会与整个字符串匹配。

如果您需要最多一个标点字符,则需要匹配单个可选标点字符,前面和/或后面跟可选的字母字符。

请注意,使用\\p{Alpha}\\p{Punct}会排除数字。不允许数字。如果您想将数字视为特殊字符,请将\\p{Punct}替换为\\P{Alpha}(大写P表示 Alpha)。

public static void main(String[] args) {
    process("Australia India# Amer$ca America@! America1");
}
public static void process(String rawData) {
    Pattern pattern = Pattern.compile("\\p{Alpha}*\\p{Punct}?\\p{Alpha}*");
    for (String s : rawData.split(" ")) {
        System.out.println("My Data Elements: " + s);
        if (pattern.matcher(s).matches()) {
            System.out.println("Allowed");
        } else {
            System.out.println("Not allowed");
        }
    }
}

输出

My Data Elements: Australia
Allowed
My Data Elements: India#
Allowed
My Data Elements: Amer$ca
Allowed
My Data Elements: America@!
Not allowed
My Data Elements: America1
Not allowed

答案 1 :(得分:1)

您可以使用

^\\p{Alpha}*(?:\\p{Punct}\\p{Alpha}*)?$

<强>解释

  • ^ - 字符串开头
  • \\p{Alpha}* - 零个或多个字母
  • (?:\\p{Punct}\\p{Alpha}*)? - 一个或零(由于?量词)序列:
    • \\p{Punct} - 一次出现标点符号
    • \\p{Alpha}* - 零个或多个字母
  • $ - 字符串结束。

将其与String#matches一起使用将允许删除^$锚点,因为默认情况下该模式将被锚定:

if (input.matches("\\p{Alpha}*(?:\\p{Punct}\\p{Alpha}*)?")) { ... }

答案 2 :(得分:0)

我希望这会有所帮助。

public static void process(String rawData) {
    String[] splitData = rawData.split(" ");
    for (String s : splitData) {
        Pattern pNum = Pattern.compile("[0-9]");
        Matcher match = pNum.matcher(s);
        if (match.find()) {
            System.out.println(s + ": Not Allowed");
            continue;
        }

        Pattern p = Pattern.compile("[^a-z]", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(s);

        int count = 0;
        while (m.find()) {
            count = count + 1;
        }

        if (count > 1) {
            System.out.println(s + ": Not Allowed");
        } else {
            System.out.println(s + ": Allowed");
        }
    }

}
  

输出

澳大利亚:允许

印度#:允许

America @ !: Not Allowed

America1:不允许

答案 3 :(得分:0)

你可以通过一个简单的否定前瞻来做到这一点:

((?!\\p{Punct}{2}).)*

所以你的代码变得简单:

public void process(String rawData) {
    if (input.matches("((?!\\p{Punct}{2}).)*"))
        System.out.println("Allowed");
    } else {
        System.out.println("Not allowed");
    }
}

正则表达式断言每个字符不是{Punct}后跟另一个{Punct}

答案 4 :(得分:-1)

好的!再次编辑

您可以使用以下正则表达式

Formosa, Brazil (193 km)
Sao Luis De Montes Belos, Brazil (190 km)
Palmeiras De Goias, Brazil (190 km)

Regex

这只适用于居住在任何地方的一个标点符号。