PHP+;正则表达式在特定模式后提取字符串的部分

PHP+;正则表达式在特定模式后提取字符串的部分,php,regex,string,pattern-matching,Php,Regex,String,Pattern Matching,试图弄明白这一点,如果除了正则表达式之外还有其他方法,我愿意接受 需要采取与以下类似的模式: 一个在破折号之间有空格,另一个没有 有时可能有3个周期,有时可能有4个周期 在这两个期间之间,始终会有数字,这些数字可能会有所不同,例如1.111.1 1.1.1-50 1.1.1-50 1.1.1-50 1.1.1-50 以上内容应输出至: 字符串1:1.1 第2组:1 第3组:50 我不知道如何在最后一个句号和破折号之间选择数字,在破折号之后选择数字,并且忽略任何空格 更新:完整且有效的代

试图弄明白这一点,如果除了正则表达式之外还有其他方法,我愿意接受

需要采取与以下类似的模式:

  • 一个在破折号之间有空格,另一个没有
  • 有时可能有3个周期,有时可能有4个周期
  • 在这两个期间之间,始终会有数字,这些数字可能会有所不同,例如1.111.1

  • 1.1.1-50
  • 1.1.1-50
  • 1.1.1-50
  • 1.1.1-50
以上内容应输出至:

  • 字符串1:1.1
  • 第2组:1
  • 第3组:50
我不知道如何在最后一个句号和破折号之间选择数字,在破折号之后选择数字,并且忽略任何空格

更新:完整且有效的代码

利用hakre和Niels提供的信息,创建了以下代码:

不确定我的代码是否经过优化,但这基本上是我需要完成的

<form action="" method="post">
    <p>
        <strong>Records Range:</strong> <input type="text" name="records_range" size="30" maxlength="22" />
        <br />
        <strong>Internal ID:</strong> <input type="text" name="internal_id"  size="40" />
        <select name="id_options">
            <option value="default_internal_id">Default Internal ID</option>
            <option value="new_internal_id">New Internal ID</option>
        </select>
        <br />
        <input type="submit" value="Generate" />
    </p>
</form>

<?php 

    $id_options = NULL;                         
    if (isset($_POST['records_range'])) {   
        $id_options = $_POST['id_options'];
        $internal_id = strip_tags(trim(($_POST['internal_id'])));
        $records_range = strip_tags(trim($_POST['records_range']));
        preg_match('~^((?:\d+\.){2,3})(\d+)\s?-\s?(\d+)$~', $records_range, $record_segements);
        $range_prefix = $record_segements[1];
        $range_start = $record_segements[2];
        $range_end = $record_segements[3];
        echo "<p><strong>Record Data Generated For:</strong> ".$range_prefix.$range_start." - ".$range_end."</p>";
    }


    switch ($id_options){
        case 'default_internal_id':         
        echo "<textarea cols=\"65\" rows=\"10\">";

        // start output
        while($range_start <= $range_end){

            if($range_start < $range_end){
                echo "EUI-ZQ50-N-".$range_prefix.$range_start."\n";
            }

            else{
                echo "EUI-ZQ50-N-".$range_prefix.$range_start;
            }

            $range_start++;
        }
        echo "</textarea>";
        break;  

        case 'new_internal_id':         
        echo "<textarea cols=\"65\" rows=\"10\">";

        // start output
        while($range_start <= $range_end){

            if($range_start < $range_end){
                echo $internal_id." ".$records_prefix.$range_start"\n";
            }

            else{
                echo $internal_id." ".$records_prefix.$range_start;
            }

            $range_start++;
        }
        echo "</textarea>";
        break;
        default:
         echo "<h4>Example:</h4>";
         echo "<p><strong>Records Range</strong>: 1.22.333.444-500 = 1.22.333.444 <strong>THROUGH</strong> 500</p>";
    }

?>      


记录范围:

内部ID: 默认内部ID 新的内部ID


从我的头顶看,这应该在
preg\u match
中起作用:

/^([0-9\\.]+?)([0-9]+) ?\- ?([0-9]+)$/

创建三个与零件匹配的组

明确表示在第一组中,数字+点需要重复两次:

  ~^((?:\d+\.){2,3})(\d+)\s?-\s?(\d+)$~
    `-------1------´`-2-´       `-3-´
            ^         ^           `--- end number
            |         | 
            |    middle number
            |       
first two/three incl. the dot
所有不匹配的东西,比如空格和破折号,都不会被捕获,这也可以被描述为“忽略”

我希望这是有帮助的,并显示了它的工作原理

:


您没有显示任何代码。所以输出是相对的。你可以对它进行编码。别误会我的意思,描述很详细,只是缺少示例代码,说明您已经取得了多大的进步,或者说明了要使用的上下文。你可能需要一个整数数组吗?输入已经是字符串还是数组等。。这些东西很容易用几行代码来展示,这将改进您在这里得到的所有答案。如果您询问如何为Notepad++编写正则表达式,您应该这样说。这可以解释为什么没有任何代码示例。如果是的话,也是这样。因此,答案中给出的正则表达式可能不适用于您,因为您的问题不清楚您所问的是什么。我很抱歉,我不知道php和notepad++处理正则表达式的方式不同,我对缺乏细节表示歉意。我的帖子现在展示了我试图实现的目标。我的意思是在编辑器中搜索并替换Notepad++regex。如果您在编辑器中有PHP代码并执行它,那将是另一双鞋。我只是想知道,因为您没有添加代码,但现在清楚地表明它是关于PHP的。感谢您如此快速的响应。所以我在notepad++中尝试了这个表达式,它选择了1.1.1-1中的所有1,只要它们是个位数。因此,对于1.111.1-1或1.111.111-1,它现在确实选择了111,只是1。不过很有趣,因为我的理解比我想象的要少。:)应该在案例中说明;)使用
/^([0-9\\.]+?)([0-9]+?)?\-?([0-9]+)$/
,只需测试它并捕获这些情况(在第一次匹配时切换贪婪)。@Damainman:注意Notepad++处理正则表达式的方式可能与PHP不同。我只是说,如果你在这里要求一个PHP正则表达式,请在PHP代码中尝试。用验证我的解决方案,效果很好。很抱歉,我不知道notepad++和PHP对正则表达式的处理不正确。我是新来的。感谢preg_match validator链接Niels!I+1是你的帖子。你把它和前瞻性结合起来有点过于复杂了——用例只是把match 1描述为“直到最后一个数字的所有内容”,它可能包括两个以上的句点,你可以像我一样贪婪地使用它们。但是您的解决方案不正确,因为它需要两个句点。@Niels:答案中没有前瞻性(如果您的意思是
(?:[…])
,则只有一个不匹配的组)。但是你是对的,OP写到有时候有4个句点,所以我需要把第一部分的答案改为2,3。(我想这就是OP的意思,我通常把句号读成点,但那可能是我的英语不好。)你的英语有时会用到我的正则表达式术语;)点和句号几乎在所有情况下都是同义词。是的,我认为我写的东西离我不太远,但语言是通过使用它们来学习的,所以承认错误并谈论/写它是很好的:)我的点计数更灵活(也适用于
1.1.1.1.1.1
1.1
),我怀疑我忽略了组参考,所以速度快了一点。但我不知道这是否真的值得注意。最大的光学差异是@hakre使用
\d
(任何数字字符),而我更喜欢使用更详细但等效的
[0-9]
符号,但它们在内部由regexp引擎进行相同的处理,这只是不同的编程风格。
<?php

$strings = [
    '1.1.1-50',
    '1.1.1 - 50',
    '1.1.1- 50',
    '1.1.1 -50',
    '1.1.1.1 -50',
];

foreach($strings as $subject)
{
    $pattern = '~^((?:\d+\.){2,3})(\d+)\s?-\s?(\d+)$~';
    $result  = preg_match($pattern, $subject, $matches);

    printf("%s -> %s\n", var_export($subject, 1), var_export($matches, 1));
}