如何为字符串构建正则表达式?

时间:2012-10-31 17:35:17

标签: java android regex

我怎么能把它写成正则表达式?

“BLOCKa中#123#456”

我使用#符号来分割数据中的参数 参数是块名,startX坐标,启动Y corrdinate

这是我的QR码中嵌入的数据。因此,当我扫描QR时,我想检查它们是否正在扫描它们的QR。为此,我需要一个正则表达式的上述语法。

我的方法主体

public void Store_QR(String qr){
   if( qr.matches(regular Expression here)) {
      CurrentLocation = qr;
   }
   else // Break the operation
}

4 个答案:

答案 0 :(得分:5)

您指定的信息根本不使用正则表达式。

尝试以更一般的方式使用它。

如果您确实需要扫描“blocka#123#456”,请使用qr.contains("blocka#123#456");

答案 1 :(得分:3)

这取决于你想要匹配的东西。

  1. 以下是一些正则表达式命题:

    ^blocka#[0-9]{3}#[0-9]{3}$
    ^blocka#[0-9]+#[0-9]+$
    ^blocka(#[0-9]{3}){2}$
    ^blocka(#[0-9]+){2}$
    ^blocka(#[0-9]{3})+$
    ^blocka(#[0-9]+)+$
    
  2. 否则,只需使用contains()或类似内容。

答案 2 :(得分:1)

myregexp.com很高兴做一些测试。

官方Java Regex Tutorial可以学习,包括大多数需要了解的内容。

Pattern文档还包括上面教程中缺少的花哨的预定义字符类。

您没有在您给出的示例中指定任何必须是常规的内容。只有有规则来验证输入时,正则表达才有意义。

如果必须完全"blocka#123#456",那么"blocka#123#456""^blocka#123#456$"将作为正则表达式。 ^$之间的东西意味着内部的正则表达式必须跨越输入的开头到结尾。有时需要,通常是一个好主意,把它放在你的正则表达式。

如果blocka是动态的,请将其替换为[a-z]+,以匹配任何长度至少为1的小写字母az的序列。block[a-z]匹配blockablockb等 并且[a-z]{6}将匹配正好6个字母的任何序列。 [a-zA-Z]还包含大写字母,\p{L}匹配任何字母,包括unicode内容(例如Blüc本)。

#匹配#。就像任何没有特殊正则表达式(\ ^ $ . | ? * + ( ) [ ] { })字符的角色一样。 [^#]匹配除#之外的所有字符。

关于数字:[0-9]+\d+是多个数字的通用模式,[0-9]{1,4}会匹配1-4个数字中的任何数字,例如007,{{ 1}},5。例如9999仅匹配(?:0|[1-9][0-9]{0,3})0之间的数字,并且不允许前导零。 9999是一个非捕获组,不会影响您可以通过(?:STUFF)提取的组。对Matcher#group(1..?)的逻辑分组很有用。 |的含义是:单个(?:0|[1-9][0-9]{0,3}) OR(1x 0 - 1后跟0到3 x 9 - 0

9非常常见,因此有一个预定义:[0-9](数字)。正则表达式\d位于正则表达式\\d内,因为您必须转义String

所以你的一些选择是

  • \绝对符合所有内容
  • ".*"匹配"^[^#]+(?:#[^#]+)+$"分隔的任何内容,例如#
  • "hello #world!1# -12.f #本#foo#bar"匹配"^blocka(#\\d+)+$",后跟至少一组以blocka分隔的数字,例如#
  • blocka#1#12#0007#949432149#3只有在找到"^blocka#(?:[0-9]|[1-9][0-9]|[1-3][0-9]{2})#[4-9][0-9]{2}$"后跟数字0 - 399,然后是blocka#,最后是数字400-999
  • 时才匹配
  • #只匹配该字符串。

所有这些都是与您给出的示例匹配的正则表达式。

但它可能就像

一样简单
"^blocka#123#456$"

public void Store_QR(String qr){
   if( qr.matches("^blocka#\\d+#\\d+$")) {
      CurrentLocation = qr;
   }
   else // Break the operation
}

  

BlockName#start_X #start_Y任何块名称..以字符串“block”开头,后跟两个整数

我认为一个好的正则表达式是private static final Pattern QR_PATTERN = Pattern.compile("^blocka#(\\d+)#(\\d+)$"); public void Store_QR(String qr){ Matcher matcher = QR_PATTERN.matcher(qr); if(matcher.matches()) { int number1 = Integer.valueOf(matcher.group(1)); int number2 = Integer.valueOf(matcher.group(2)); CurrentLocation = qr; } else // Break the operation } ,从"^block\\w+#\\d+#\\d+$"开始,然后是"block" - az - {{的任意组合1}},A - Z0(即9)后跟_,数字,\w,数字。

会匹配##block_#0#0,但不匹配blockZ#9#9,因为根本没有名称且与block_a_Unicorn666#0000#1234不匹配,因为字母代替数。由于大写字母B,也不会匹配block#1#2

如果名称部分(blockName#123#abc)过于宽松(Block_a#123#456\\w+将是合法名称),请使用例如___,不允许使用数字和名称的内容只能由一个可选的_123分隔,之后必须有字母。允许"^block_?[a-zA-Z]+#\\d+#\\d+$"__a,但不允许a_ABc_。如果要允许名称_a_b中的数字,则使用字符类。

答案 3 :(得分:0)

我建议:

[a-z]+#\d+#\d+

如果你想抓住3个部分:

([a-z]+)#(\d+)#(\d+)

Matcher.group( 1, 2 or 3 )返回部分