Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 分解有关大写或数字字符的UTF8字符串_Php_Regex_String_Utf 8_Preg Replace - Fatal编程技术网

Php 分解有关大写或数字字符的UTF8字符串

Php 分解有关大写或数字字符的UTF8字符串,php,regex,string,utf-8,preg-replace,Php,Regex,String,Utf 8,Preg Replace,例如,我可以拆分包含大写字母的字符串,如下所示: function splitAtUpperCase($string){ return preg_replace('/([a-z0-9])?([A-Z])/','$1 $2',$string); } $string = 'setIfUnmodifiedSince'; echo splitAtUpperCase($string); 输出为“自后未修改时设置” 但我需要一些修改: 当这些字符以字符串形式存在时,该代码段不会处理这些情况:Ö

例如,我可以拆分包含大写字母的字符串,如下所示:

function splitAtUpperCase($string){
    return preg_replace('/([a-z0-9])?([A-Z])/','$1 $2',$string);
}

$string = 'setIfUnmodifiedSince';
echo splitAtUpperCase($string);
输出为“自后未修改时设置”

但我需要一些修改:

  • 当这些字符以字符串形式存在时,该代码段不会处理这些情况:
    ÖĞŞ࢜
    。我不想音译这些字符。然后我就失去了这个词的意思。我需要使用一些UTF字符。该代码将“Here ch on Then”改为“Here ch on Then”
  • 我也不想拆分大写缩写。如果单词是“我知道你会尽快来这里”,我需要将它转换为“我知道你会尽快来这里”
  • 如果所有字母都是大写,则不要爆炸。比如“DONTCOMEHERE”
  • 也分解数值。“2013年底前”至“2013年底前”
  • 如果第一个字符是散列键(#),则分解
案例和预期结果

  • “明天来这里”=>“明天来这里”
  • “今天吻你”=>“今天吻你”
  • “过来”=>“过来”
  • “NEVERSAYIT”=>“NEVERSAYIT”
  • “2013年将会到来”=>“2013年将会到来”
  • “2013年底前”=>“2013年底前”
  • “我知道”=>“我知道”
  • “#whatiknow”=>“#whatiknow”
  • 对于这些情况,我使用后续的
    str\u replace
    操作。我寻找一个简短的解决方案,它不会让循环检查单词。如果可能的话,最好将其作为
    preg\u replace

    编辑:任何人都可以通过更改此PHP小提琴中的
    convert
    函数来尝试他的解决方案:

    /([:lower:][:digit:][])?([:upper:][]+)/u
    应该这样做

    这里
    /u
    用于Unicode字符。而
    ([[:upper:][]+)
    用于大写字母的顺序

    注意。字母的大小写取决于您使用的字符集

    一些注意事项:

    • 用于搜索大写和小写字母(甚至是标题大小写字母,f.ex.
      LjNjDz
    • 明天来这里
      &
      我知道
      在使用一些字典查找确切的单词之前,一种方法无法使用

      因为如果你想把
      明天来这里
      翻译成
      明天来这里
      我知道
      将是
      IK现在
      (甚至是
      IK现在

      如果你想把
      我知道
      翻译成
      我知道
      明天来这里
      将是
      明天来

    我的解决方案:(不包括非字母和非数字字符)

    您需要Unicode正则表达式:
    \p{Lu}表示大写
    \p{Li}表示小写

    因此,您的用法如下所示:
    /([\p{Ll}0-9])?([\p{Lu}])/

    嗯,但我仍然认为这不是一个好的解决方案。(测试驱动设计中为数不多的缺陷之一)

    我采取了稍微不同的方法。我没有试图写一个正则表达式来表示单词之间的位置应该是什么样子,而是写了一个正则表达式来查找所有明显是单词的东西,然后就内爆了

    function convert($keyword) {
       $wResult = preg_match_all('/(^I|[[:upper:]]{2,}|[[:upper:]][[:lower:]]*|[[:lower:]]+|\d+|#)/u', $keyword, $matches);
       return implode(' ',$matches[0]);
    }
    
    正如你所看到的,这是我认定的一个词:

    ^I                 A capital I at the beginning of the string.  Break point: Icons.
    [[:upper:]]{2,}    Consecutive capitals.  Break Point:  WellIKnowThat
    [[:upper:]][[:lower:]]*    A single Capital followed by some lower case letters
    [[:lower:]]+       A string of lower case letters
    \d+                A string of digits
    #                  A literal #
    
    它并不完美-仍然有许多断点。你可以继续完善这些词的定义,但坦率地说,总会有一个你抓不到的边缘案例。然后慢慢地扩展这个正则表达式,直到它完全无法管理为止。你可以尝试使用字典,但最终也会失败。你怎么处理“旋风”?还是“伊坦”?那是“IT an”还是“I Tan”?举个例子?这是在我试图抓住我的一些错误之后。它变得如此巨大,而想出一条断开的线仍然是微不足道的。这个函数是关于度的-花多少时间来教你的算法世界上所有语言的有趣之处

    编辑:在做了一些工作之后,决定我可以被分离出来作为它自己的单词,当且仅当它后面紧跟着一个大写字母和一个小写字母

    我还添加了一些新的测试用例:

     convert("Icons") = "Icons"
     convert("WellIKnowThat") == "Well I Know That"
     convert("ITan") == "I Tan"
     convert("whirlwind") == "whirlwind"
    
    我想这和今天一样好。按优先顺序排列的最后一组“单词定义”是:

  • 大写字母I,前提是后跟一个大写字母和一个小写字母:
    I(?=[:Upper:][:lower:]])
  • 两个或多个连续的大写字母:
    [[:upper:]{2,}
  • 一个大写字母,后跟尽可能多的小写字母:
    [[:upper:][[:Lower:]*
  • 一个或多个连续小写字母:
    [:lower:]+
  • 一个或多个连续数字:
    \d+
  • 文字磅符号:
    #

  • 我添加了另一个单词定义,一个测试用例。新的单词定义与
    I
    的规则匹配,但与
    A
    匹配,后者是英语中唯一的一个字母单词。

    如何正则表达式将知道
    I
    IKnow
    中是不同的单词?这是不可能的。与Asphere相同。如果随后有两个大写字母和一个小写字母,则将其拆分,如果有两个以上大写字母,则存在缩写,因此,在没有得到下一个单词的第一个字母的情况下拆分它。那么你想将
    JScript
    拆分为
    J Script
    ?顺便问一下,除了另一个问题中的代码片段之外,你做了什么?什么逻辑可以将
    明天这里拆分为
    明天这里
    IKnow
    拆分为
    我知道的
    而不是
    IK现在
    ?谢谢你的回答,看起来很好。我不打算使用非字母数字字符。我没有选择使用字典。所以也许可以忽略“IKnowThat”。如果散列(#)是第一个字符,就不可能拆分吗?否则我将添加
    $wResult=str_替换(“#“,”#“,$wResult)到结果字符串
    
     convert("Icons") = "Icons"
     convert("WellIKnowThat") == "Well I Know That"
     convert("ITan") == "I Tan"
     convert("whirlwind") == "whirlwind"