R--将前导零添加到字符串,没有固定的字符串格式

时间:2018-01-24 21:47:31

标签: r leading-zero

我有一个列如下。

9453,55489,4588,18892,4457,2339,45489HQ,7833HQ

如果数字小于5位,我想添加前导零。但是,有些数字到底有“HQ”,有些没有。(我确实检查了其他帖子,他们在“HQ”部分没有类似的问题)

所以最终期望的输出应该是:

09453,55489,04588,18892,04457,02339,45489HQ,07833HQ

任何想法如何做到这一点?非常感谢你阅读我的帖子!

4 个答案:

答案 0 :(得分:6)

使用正则表达式的单行:

<DatePicker.CalendarStyle>
  <Style TargetType="Calendar">
    <Setter Property="CalendarDayButtonStyle">
      <Setter.Value>
        <Style TargetType="CalendarDayButton">
          <Setter Property="MinWidth"
                  Value="5" />
          <Setter Property="MinHeight"
                  Value="5" />
          <Setter Property="FontSize"
                  Value="10" />
          <Setter Property="Padding"
                  Value="5,1,5,1" />
          <Setter Property="HorizontalContentAlignment"
                  Value="Center" />
          <Setter Property="VerticalContentAlignment"
                  Value="Center" />
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="CalendarDayButton">
                <Border x:Name="border"
                        BorderBrush="Transparent"
                        BorderThickness="1"
                        Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}">
                  <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                </Border>
                <ControlTemplate.Triggers>
                  <!--Trigger Property="IsToday" Value="True">
                    <Setter TargetName="border" Property="Background" Value="#FFAAAAAA" />
                  </Trigger-->
                  <Trigger Property="IsSelected" Value="True">
                    <Setter TargetName="border" Property="Background" Value="#FFBADDE9" />
                  </Trigger>
                  <Trigger Property="IsBlackedOut" Value="True">
                    <Setter TargetName="border" Property="TextBlock.Foreground" Value="#FFCCCCCC" />
                  </Trigger>
                  <Trigger Property="IsFocused" Value="True">
                    <Setter TargetName="border" Property="BorderBrush" Value="#FF45D6FA" />
                  </Trigger>
                </ControlTemplate.Triggers>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </Setter.Value>
    </Setter>
  </Style>
</DatePicker.CalendarStyle>

说明:

my_strings <- c("9453", "55489", "4588", 
      "18893", "4457", "2339", "45489HQ", "7833HQ")

gsub("^([0-9]{1,4})(HQ|$)", "0\\1\\2",my_strings)

[1] "09453"   "55489"   "04588"   "18893"   
    "04457"   "02339"   "45489HQ" "07833HQ"

括号按顺序表示捕获组。因此^ start of string [0-9]{1,4} one to four numbers in a row (HQ|$) the string "HQ" or the end of the string 表示0\\1\\2后跟第一个捕获组0和第二个捕获组[0-9]{1,4}

当然,如果有5个数字,那么正则表达式不匹配,所以它不会改变。

答案 1 :(得分:3)

另一种尝试,也适用于"123""1HQR"

等情况
x <- c("18893","4457","45489HQ","7833HQ","123", "1HQR")
regmatches(x, regexpr("^\\d+", x)) <- sprintf("%05d", as.numeric(sub("\\D+$","",x)))
x
#[1] "18893"    "04457"    "45489HQ"  "07833HQ"  "00123"    "00001HQR"

这基本上可以在字符串(^\\d+)的开头找到任何数字,并用零填充(via sprintf)字符串替换它们,该字符串通过删除任何非数字字符而被子集化( \\D+$)从字符串的末尾开始。

答案 2 :(得分:3)

我打算使用sprintf方法,但发现stringr包提供了一个非常简单的解决方案。

library(stringr)
x <- c("9453", "55489", "4588", "18893", "4457", "2339", "45489HQ", "7833HQ")
[1] "9453"    "55489"   "4588"    "18893"   "4457"    "2339"    "45489HQ" "7833HQ"

可以使用一个简单的stringr::str_pad()函数转换它:

stringr::str_pad(x, 5, side="left", pad="0")
[1] "09453"   "55489"   "04588"   "18893"   "04457"   "02339"   "45489HQ" "7833HQ" 

如果即使总字符串宽度> 5也需要填充数字,那么数字和文本需要用正则表达式分隔。 以下将有效。它将正则表达式匹配与非常有用的sprintf()函数结合起来:

sprintf("%05.0f%s", # this encodes the format and recombines the number with padding (%05.0f) with text(%s)
        as.numeric(gsub("^(\\d+).*", "\\1", x)), #get the number
        gsub("[[:digit:]]+([a-zA-Z]*)$", "\\1", x)) #get just the text at the end
[1] "09453"   "55489"   "04588"   "18893"   "04457"   "02339"   "45489HQ" "07833HQ"

答案 3 :(得分:1)

我们只能使用class item { name: string; order: number; } let onUp = new Rx.Subject<item>(); let list = new Rx.BehaviorSubject<item[]>([ { name: "7", order: 70 }, { name: "2", order: 20 }, { name: "5", order: 50 }, { name: "3", order: 30 }, { name: "4", order: 40 }, { name: "6", order: 60 }, { name: "1", order: 10 } ]); list.subscribe(console.log); // onUp.subscribe(anItem => { onUp .withLatestFrom(list, (item, itemList) => { return { item: item, itemList: itemList }; }) .subscribe(itemWithList => { let numberList: item[] = itemWithList.itemList.sort( (a, b) => a.order - b.order ); let orderToUp: number = itemWithList.item; let index = numberList.findIndex(x => x.order === orderToUp); let ddvalue = numberList[index]; let preddvalue = numberList[index - 1]; console.log(ddvalue); let preddvalueOrder = preddvalue.order; preddvalue.order = ddvalue.order; ddvalue.order = preddvalueOrder; list.next(numberList); }); onUp.next(30); sprintf()分割部件,然后将它们重新组合在一起。

gsub()

使用@thelatemail的数据:

sprintf("%05d%s", as.numeric(gsub("[^0-9]+", "", x)), gsub("[0-9]+", "", x))
# [1] "18893"    "04457"    "45489HQ"  "07833HQ"  "00123"    "00001HQR"