【问题标题】:Regular Expression: Matching a string until certain characters正则表达式:匹配字符串直到某些字符
【发布时间】:2013-09-06 10:00:42
【问题描述】:

我正在尝试编写一个正则表达式,它应该在找到空格后跟连字符“-”的部分显示一个字符串。如果它没有找到这个模式,它应该显示整个字符串。字符串中可以有其他空格或连字符。

以下正则表达式适用于大多数字符串值,其中所需的部分包含在 $1 中:

^([^ ]+[^-]+)( -).+

输入字符串并在上述正则表达式的第1组中匹配 -

  • 伦敦-巴黎东京 --> 伦敦-巴黎
  • 伦敦马德里-巴黎-柏林-罗马-东京-->伦敦马德里
  • 伦敦巴黎-柏林东京-->伦敦巴黎
  • 伦敦巴黎 --> 伦敦巴黎

但是,上面的正则表达式与以下情况不匹配:

  • 伦敦巴黎(一些文字)-柏林/东京

我尝试了一些正则表达式的变体,也有负前瞻,但无济于事。

任何帮助将不胜感激! 谢谢

编辑: 感谢大家提供有用和解释性的建议,但下面@Vince 的回答非常适合我的需求。我在下面添加了评论

【问题讨论】:

    标签: java regex perl


    【解决方案1】:

    我会使用一个非贪婪的量词并在它之后进行双重检查,无论是空格后跟连字符还是行尾:

    #!/usr/bin/env perl
    
    use warnings;
    use strict;
    
    while (<DATA>) {
            m/^(.*?)(?:\s+-|$)/ && print "$1\n";
    }
    
    __DATA__
    London-Paris Tokyo
    London Madrid - Paris-Berlin-Rome - Tokyo
    London Paris - Berlin Tokyo
    London Paris
    London Paris (some-text) - berlin/tokyo
    

    它产生:

    London-Paris Tokyo
    London Madrid
    London Paris
    London Paris
    London Paris (some-text)
    

    【讨论】:

    • 此正则表达式中是否需要行首符号:^?
    • @user4035:不是真的,但也没有害处。
    • @Birei - 感谢您的回答!它作为 Perl 解决方案非常完美(这是我作为第一步尝试的),但是当我在 JasperReport .jrxml 文件中复制正则表达式时(它使用 Java 编译,我猜它与 Perl 正则表达式样式兼容),我得到编译错误。知道那里需要修改什么吗?
    • @nkrgupta 在 Java 中,您需要将 `, change \s` 双重转义为 \\s
    • @nkrgupta:我不习惯java,但是regex^$ 之间的字符串)会给你编译错误吗?我认为语法是相似的,所以问题将在另一个地方。除此之外,我认为在java 中必须转义反斜杠。抱歉,我无法在这个问题上提供更多帮助。
    【解决方案2】:

    你的正则表达式匹配

    start of the line
    followed by one or  more non-whitespaces
    followed by one or more non-hyphens
    followed by whitespace
    followed by hyphen
    followed by one or more anything
    

    这不是你想要的。你想要

    one or more anything
    followed by whitespace
    followed by hyphen
    followed by one or more anything
    

    您可以使用以下正则表达式实现此目的

    ^(.+)\s-.+$
    

    如果你想匹配\s-的第一个组合,你可以使用非贪婪的+?,即

    ^(.+?)\s-.+$
    

    虽然这只会匹配,如果字符串中有-。如果你想匹配,即使不是这样,你必须让那部分是可选的。

    ^(.+?)(\s-.+)?$
    

    现在正则表达式将匹配任何字符串,如果字符串包含-,它将把之前的部分保存在$1中。

    【讨论】:

    • 谢谢@Vince。你的最后一个选项似乎适用于我的情况,我会试试你的正则表达式!
    • @M42 请定义“不起作用”,因为我对其进行了测试,并且它适用于这两个字符串。
    • @nkrgupta 如果您接受我的回答,如果这是您要使用的解决方案,我将不胜感激:)
    • @Vince:对于London Paris (some-text) - berlin/tokyo,它在第 1 组中返回 London Paris (some-text)。这是不想要的。
    • @Vince - 实际上,稍作修改,最后一个正则表达式就可以满足我的需要。我实际上正在使用一个名为 iReport 设计器的工具,它使用 Groovy,并且我可以在 .jrxml 文件中只使用条件评估(条件?“真”:“假”)。所以我尝试使用Java的replaceAll函数和正则表达式来输出带有修改的字符串,如果满足任何条件(如果字符串包含一个空格后跟连字符,则只打印第一次出现“-”之前的部分) .谢谢!
    【解决方案3】:

    你也可以使用这样的东西(Java 代码):

    String str = "London Paris";
    String substr[] = str.split("\\s+-");
    return substr[0];
    

    它适用于案例用途:

    London-Paris Tokyo --> London-Paris
    London Madrid - Paris-Berlin-Rome - Tokyo --> London Madrid
    London Paris - Berlin Tokyo --> London Paris
    London Paris --> London Paris
    

    编辑:使用 ReplaceAll:

    str.replaceAll("\\s*-.*", "")
    

    【讨论】:

    • 我实际上正在使用一个名为 iReport 设计器的工具,它使用 Groovy,并且我可以在 .jrxml 文件中只使用条件评估 (condition?"true":"false")。所以我尝试使用Java的replaceAll函数和正则表达式来输出带有修改的字符串,如果满足任何条件(如果字符串包含一个空格后跟连字符,则只打印第一次出现“-”之前的部分)
    • 不确定我是否得到了 replaceAll 部分,但我还添加了使用 replaceAll 执行任务的代码。
    • 谢谢@Averroes。您使用 replaceAll 的解决方案适用于大多数情况,除了连字符不跟随空格的情况。无论如何,连字符之前有切断,这不应该发生。上面文斯的解决方案现在对我有用。但我很想知道您是否可以修改您的 replaceAll 解决方案以涵盖所有情况!
    【解决方案4】:

    我认为你的问题倒退了。您正在尝试查找空格/连字符之前的文本并在您需要做的是找到空格/连字符之后的文本并将其替换为任何内容时提取它。这样,只有在正则表达式匹配时才会执行操作,否则您将保留原始文本。 我不是 Perl 程序员,但我认为你想要这样的东西:

    $string =~ s/ -.*$//;
    

    【讨论】:

    • 嗨,戴夫,感谢您的回答!你是对的,我实际上也在尝试做你所说的,但不知何故直到现在才部分成功。也会尝试你的正则表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2010-12-20
    • 2015-12-11
    相关资源
    最近更新 更多