正则表达式提取带有两个点分隔部分的主题标签

时间:2019-05-29 08:38:43

标签: java regex

我正在尝试创建一个正则表达式,以便从字符串中提取一些文本。我想从网址或普通短信中提取文本,例如:

endpoint/?userId=#someuser.id

OR

Hi #someuser.name, how are you?

从这两者中,我都希望从消息中准确提取#someuser.name,从URL中提取#someuser.id。从URL和消息中提取的字符串可能很多。

我的正则表达式当前如下所示:

(#[^\.]+?\.)([^\W]\w+\b)

它工作正常,但只有一种情况,我不知道该怎么做-例如:

不应匹配以下字符串:# .id#.id#.之间必须至少有一个字符。这些字符之间不得有一个或多个空格。

如何使用当前的正则表达式来做到这一点?

4 个答案:

答案 0 :(得分:2)

您可以使用

String regex = "#[^.#]*[^.#\\s][^#.]*\\.\\w+";

请参见regex demoits graph

enter image description here

详细信息

  • #-一个#符号
  • [^.#]*-除.#以外的零个或多个字符
  • [^.#\\s]-除.#和空格之外的任何字符
  • [^#.]*--除.#之外的零个或多个字符
  • \.-一个点
  • \w+-1个以上的字符(字母,数字或_)。

Java demo

String s = "# #.id\nendpoint/?userId=#someuser.id\nHi #someuser.name, how are you?";
String regex = "#[^.#]*[^.#\\s][^#.]*\\.\\w+";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(0)); 
} 

输出:

#someuser.id
#someuser.name

答案 1 :(得分:1)

您可以尝试以下正则表达式:

#(\w+)\.(\w+)

demo

注释:

  • 如果不想捕获任何组,请删除括号。
  • 在您的Java正则表达式字符串中,您需要对每个\进行转义
  • 这给出了#(\\w+)\\.(\\w+)
  • 如果id仅由数字组成,则可以通过\w将第二个[0-9]更改为
  • 如果username包含字母,数字和下划线以外的其他字符,则必须将\w更改为具有明确定义的所有授权字符的字符类。

代码示例:

String input = "endpoint/?userId=#someuser.id Hi #someuser.name, how are you? # .id, #.id.";
Matcher m = Pattern.compile("#(\\w+)\\.(\\w+)").matcher(input);
while (m.find()) {
    System.out.println(m.group());
}

输出:

#someuser.id
#someuser.name

答案 2 :(得分:1)

重新定义的要求是:

  • 我们搜索模式#A.B
  • A可以是任何字符,除了空格以外,也不能包含#.
  • B只能是常规的ASCII字母或数字

将这些要求转换为(可能的)正则表达式:

#[^.#]+((?<!#\\s+)\\.)[A-Za-z0-9]+

说明:

#[^.#]+((?<!#\\s+)\\.)[A-Za-z0-9]+  # The entire capture for the Java-Matcher:
#                                   #  A literal '#' character
 [^.#]+                             #  Followed by 1 or more characters which are NOT '.' nor '#'
       (          \\.)              #  Followed by a '.' character
        (?<!     )                  #  Which is NOT preceded by (negative lookbehind):
            #                       #   A literal '#'
             \\s+                   #   With 1 or more whitespaces
                      [A-Za-z0-9]+  #  Followed by 1 or more alphanumeric characters
                                    #  (PS: \\w+ could be used here if '_' is allowed as well)

测试代码:

String input = "endpoint/?userId=#someuser.id Hi #someuser.name, how are you? # .id #.id %^*#@*(.H(@EH Ok, # some spaces here .but none here #$p€©ï@l.$p€©ï@l that should do it..";
System.out.println("Input: \""+ input + '"');

System.out.println("Outputs: ");
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("#[^.#]+((?<!#\\s+)\\.)[A-Za-z0-9]+")
                                                         .matcher(input);
while(matcher.find())
  System.out.println('"'+matcher.group()+'"');

Try it online.

哪个输出:

Input: "endpoint/?userId=#someuser.id Hi #someuser.name, how are you? # .id #.id %^*#@*(.H(@EH Ok, # some spaces here .but none here #$p€©ï@l.$p€©ï@l that should do it.."
Outputs: 
"#someuser.id"
"#someuser.name"
"#@*(.H"
"# some spaces here .but"

答案 3 :(得分:0)

#(\w+)[.](\w+)

导致两组,例如

endpoint/?userId=#someuser.id -> group[0]=someuser and group[1]=id