Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正则表达式只允许Java字符串中有一个标点字符_Java_Regex - Fatal编程技术网

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

正则表达式只允许Java字符串中有一个标点字符,java,regex,Java,Regex,我需要解析原始数据,并允许字符串可以包含字母和一个标点字符 以下是我迄今为止所做的工作: public class ProcessRawData { public static void main(String[] args) { String myData = "Australia India# America@!"; ProcessRawData data = new ProcessRawData(); data.process(myData); } publi

我需要解析原始数据,并允许字符串可以包含字母和一个标点字符

以下是我迄今为止所做的工作:

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
预计它不应该印刷美国@因为它包含多个标点符号字符

我想我可能需要使用量词,但不确定将它们放在哪里,以便只允许一个标点符号

有人能帮忙吗?

好的!重新编辑

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

^[A-Za-z]*[!"\#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]?[A-Za-z]*$
^[A-Za-z]*[!“\\\\$%&'()*+,\-.\/:;?@\[\\\]^{{124;}~]?[A-Za-z]*$


这只适用于任何位置的一个标点符号。

我希望这会有所帮助

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");
        }
    }

}
输出

澳大利亚:允许

印度:允许

美国:不允许

美国1:不允许

你应该在循环外编译你的代码

使用时,不需要使用
^
$
,因为它将与整个字符串匹配

如果最多需要一个标点符号,则需要匹配一个可选标点符号,前面和/或后面是可选字母

<>请注意,使用<代码> \p{Alph}} /代码>和<>代码> \p{t} }/COD>不包括数字。将不允许数字。如果要将数字视为特殊字符,请用<代码> > \p{Alph}} /代码>替换<代码> \p{t} <代码>(大写p表示非alpha)。

输出

我的数据元素:澳大利亚
允许
我的数据元素:印度#
允许
我的数据元素:Amer$ca
允许
我的数据元素:美国@!
不准
我的数据元素:America1
不准
您可以使用

^\\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}*)?")) { ... }

您可以通过简单的负面展望来实现:

((?!\\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}

参见。@WiktorStribiżew,正则表达式将允许
a#b$c
,它有两个特殊字符,但它们不在一起。我认为不允许两个连续字符。如果所有字符串中只有两个字符是非连续的,那么
“^(?)?!(?:\\P{Punct}*\\P{Punct}{2})[\\P{Punct}\\P{Alpha}]+$”
应该有帮助,或者更好:
^\\P{Alpha}*(?:\\P{Punct}\\P{Alpha}*)?$
。我没有发表文章,因为我看到标题和示例之间存在差异。@WebNoob请检查我的评论,让我知道上面的模式对你有用。应该有一些东西。@WiktorStribiżew谢谢,第二个正则表达式适用于我正在寻找的内容。不应该允许使用“America1”吗?@erolkaya84只能包含字母表和一个特殊字符“如果你将一个数字归类为特殊字符,那么是的,但它通常不是这样分类的。这就是为什么我在第4段中指出它,只是为了确保OP知道它。@Andreas非常感谢这些提示和解决方案。它工作得非常好。
\w
包括
\u
和数字(0-9)“这不是OP所需要的。而且,只有当特殊字符在结尾时才匹配,而不是嵌入在中间。”安德烈亚斯:后面的问题不清楚。正文没有关于位置的任何说明,但是在示例中,特殊字符总是在末尾。将<代码> \W+< /代码>改为<代码> [AZ-Z]。+
,这个答案可能完全正确。问题是“可以包含字母表和一个特殊字符。”单词“contain”的意思是任何地方,而不仅仅是结尾。@Andreas现在您可以测试正则表达式:)不。这与
Th1s\u真的很糟糕
,这显然是不应该的。当您知道单词(
s
)不能包含任何空格(您在空格上拆分,记得吗?)时,为什么要在字符类中包含空格?OP说“可以包含字母,只有一个特殊字符”字母不包括数字。你认为数字(0~9)是一个特殊字符吗?数字通常不是这样分类的,但您的代码允许使用单个数字。OPs原始正则表达式
[\\p{Alpha}\\p{Punct}]
完全排除了数字。最新的更新将给出正确的结果,但考虑到一个复杂的问题,它的代码太多了。但是,如果您想这样做,应该从数字测试中删除
不区分大小写的
,并将
compile()
调用移到loop.True之外。我会再看一次的。很高兴它对你有用。如果我的答案对你有帮助(请参阅),请考虑接受答案(见)和投票。
public void process(String rawData) {
    if (input.matches("((?!\\p{Punct}{2}).)*"))
        System.out.println("Allowed");
    } else {
        System.out.println("Not allowed");
    }
}