”匹配?

ttp71kqs  于 2021-06-29  发布在  Java
关注(0)|答案(13)|浏览(257)

我试着用正则表达式来匹配空格分隔的数字。我找不到准确的定义 \b (“单词边界”)。我以为 -12 将是一个“整数字”(匹配 \b\-?\d+\b )但这似乎行不通。我很高兴能知道解决问题的方法。
[我在Java1.6中使用java正则表达式]
例子:

Pattern pattern = Pattern.compile("\\s*\\b\\-?\\d+\\s*");
String plus = " 12 ";
System.out.println(""+pattern.matcher(plus).matches());

String minus = " -12 ";
System.out.println(""+pattern.matcher(minus).matches());

pattern = Pattern.compile("\\s*\\-?\\d+\\s*");
System.out.println(""+pattern.matcher(minus).matches());

这将返回:

true
false
true
qmb5sa22

qmb5sa221#

我想解释一下艾伦·摩尔的答案
单词边界是前面有单词字符但后面没有一个字符,或者后面有单词字符但前面没有一个字符的位置。
假设我有一个字符串“this is a cat,she's awesome”,并且我应该替换所有出现的字母“a”,只要这个字母存在于“单词的边界”,即字母 a 内部“cat”不应更换。
因此,我将执行regex(在python中)作为 re.sub("\ba","e", myString.strip()) //替换 ae 所以输出就是这个 ee 而且她是 e 维索姆

ca1c2owp

ca1c2owp2#

单词边界\b用于一个单词应为单词字符而另一个单词应为非单词字符的情况。负数的正则表达式应为

--?\b\d+\b

检查工作演示

bnl4lu3b

bnl4lu3b3#

在大多数regex方言中,单词边界是两个词之间的位置 \w 以及 \W (非单词字符),如果字符串以单词字符开头或结尾,则在字符串的开头或结尾( [0-9A-Za-z_] ).
所以,在弦上 "-12" ,它将在1之前或2之后匹配。破折号不是单词字符。

1tuwyuhd

1tuwyuhd4#

我在搜索文本时遇到了更糟糕的问题,比如 .NET , C++ , C# ,和 C . 你可能会认为计算机程序员比给一种难以编写正则表达式的语言命名更清楚。
不管怎样,这就是我发现的(主要是从http://www.regular-expressions.info,这是一个很好的站点):在大多数regex风格中,与速记字符类匹配的字符 \w 是按单词边界视为单词字符的字符。java是个例外。java支持unicode \b 但不是为了 \w . (我相信当时有一个很好的理由。
这个 \w 代表“文字字符”。它总是匹配ascii字符 [A-Za-z0-9_] . 注意包含下划线和数字(但不是破折号!)。在大多数支持unicode的版本中, \w 包含其他脚本中的许多字符。实际上包括哪些字符有很多不一致之处。一般包括字母和表意文字中的字母和数字。除了下划线和非数字的数字符号以外的连接器标点符号可能也可能不包括在内。xmlschema和xpath甚至包括 \w . 但是java、javascript和pcre只匹配ascii字符 \w .
这就是基于java的regex搜索 C++ , C# 或者 .NET (即使你记得逃过句号和加号)被 \b .
注意:我不知道该怎么处理文本中的错误,比如某人在句末的句号后没有加空格。我允许这样做,但我不确定这样做是否正确。
无论如何,在java中,如果您在文本中搜索那些奇怪的命名语言,您需要替换 \b 带有前后空格和标点符号指示符。例如:

public static String grep(String regexp, String multiLineStringToSearch) {
    String result = "";
    String[] lines = multiLineStringToSearch.split("\\n");
    Pattern pattern = Pattern.compile(regexp);
    for (String line : lines) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            result = result + "\n" + line;
        }
    }
    return result.trim();
}

然后在测试或主要功能中:

String beforeWord = "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|^)";   
    String afterWord =  "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|$)";
    text = "Programming in C, (C++) C#, Java, and .NET.";
    System.out.println("text="+text);
    // Here is where Java word boundaries do not work correctly on "cutesy" computer language names.  
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for .NET="+ grep("\\b\\.NET\\b", text));
    System.out.println("Should find: grep exactly for .NET="+ grep(beforeWord+"\\.NET"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for C#="+ grep("\\bC#\\b", text));
    System.out.println("Should find: grep exactly for C#="+ grep("C#"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java:grep with word boundary for C++="+ grep("\\bC\\+\\+\\b", text));
    System.out.println("Should find: grep exactly for C++="+ grep(beforeWord+"C\\+\\+"+afterWord, text));

    System.out.println("Should find: grep with word boundary for Java="+ grep("\\bJava\\b", text));
    System.out.println("Should find: grep for case-insensitive java="+ grep("?i)\\bjava\\b", text));
    System.out.println("Should find: grep with word boundary for C="+ grep("\\bC\\b", text));  // Works Ok for this example, but see below
    // Because of the stupid too-short cutsey name, searches find stuff it shouldn't.
    text = "Worked on C&O (Chesapeake and Ohio) Canal when I was younger; more recently developed in Lisp.";
    System.out.println("text="+text);
    System.out.println("Bad word boundary because of C name: grep with word boundary for C="+ grep("\\bC\\b", text));
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
    // Make sure the first and last cases work OK.

    text = "C is a language that should have been named differently.";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    text = "One language that should have been named differently is C";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    //Make sure we don't get false positives
    text = "The letter 'c' can be hard as in Cat, or soft as in Cindy. Computer languages should not require disambiguation (e.g. Ruby, Python vs. Fortran, Hadoop)";
    System.out.println("text="+text);
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

p、 谢谢你http://regexpal.com/ 没有谁,regex世界将会非常悲惨!

js4nwp54

js4nwp545#

单词边界可以出现在以下三个位置之一:
如果第一个字符是单词字符,则在字符串的第一个字符之前。
如果最后一个字符是单词字符,则在字符串的最后一个字符之后。
在字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。
单词字符是字母数字;减号不是。摘自正则表达式教程。

ghhkc1vu

ghhkc1vu6#

我相信你的问题是由于 - 不是单词字符。因此,单词边界将在 - ,因此不会捕获它。单词边界匹配字符串中第一个单词字符的前面和最后一个单词字符的后面,以及前面是单词字符或非单词字符,后面是相反的任何位置。还要注意单词边界是零宽度匹配。
一种可能的选择是

(?:(?:^|\s)-?)\d+\b

这将匹配以空格字符和可选破折号开始,以单词边界结束的任何数字。它还将匹配从字符串开头开始的数字。

qc6wkl3g

qc6wkl3g7#

我说什么 \b -样式regex边界实际上在这里。
简而言之,它们是有条件的。他们的行为取决于他们所处的环境。


# same as using a \b before:

(?(?=\w) (?<!\w)  | (?<!\W) )

# same as using a \b after:

(?(?<=\w) (?!\w)  | (?!\W)  )

有时候这不是你想要的。请看我的另一个答案。

ecbunoof

ecbunoof8#

当你使用 \\b(\\w+)+\\b 这意味着与只包含单词字符的单词完全匹配 ([a-zA-Z0-9]) 以你的情况为例 \\b 在regex开始的时候 -12 (用空格)但它又不能接受 -12 (无空格)
为了证明我的话:https://docs.oracle.com/javase/tutorial/essential/regex/bounds.html

brccelvz

brccelvz9#

单词边界是前面有单词字符但后面没有单词字符,或者后面有单词字符但前面没有单词字符的位置。

eimct9ow

eimct9ow10#

查看有关边界条件的文档:
http://java.sun.com/docs/books/tutorial/essential/regex/bounds.html
查看此示例:

public static void main(final String[] args)
    {
        String x = "I found the value -12 in my string.";
        System.err.println(Arrays.toString(x.split("\\b-?\\d+\\b")));
    }

打印时,请注意输出如下:
[我在字符串中找到值-。]
这意味着“-”字符不会被认为是在单词的边界上,因为它不被认为是单词字符。看起来@brianary有点击败了我,所以他得到了一张赞成票。

v2g6jxz6

v2g6jxz611#

我认为它是最后一个匹配的边界(即字符跟随)或字符串的开头或结尾。

qnyhuwrf

qnyhuwrf12#

在学习正则表达式的过程中,我真的被困在了元字符中 \b . 当我反复问自己“它是什么,它是什么”的时候,我确实不明白它的意思。在尝试使用这个网站之后,我注意到单词开头和结尾的粉红色竖线。我当时很明白它的意思。现在正是这个词( \w )-边界。
我的观点只是以极大的理解为导向。其背后的逻辑应该从另一个答案来审视。

u1ehiz5o

u1ehiz5o13#

参考:精通正则表达式(jeffrey e.f.friedl)-o'reilly
\b相当于 (?<!\w)(?=\w)|(?<=\w)(?!\w)

相关问题