除了序数指标之外,正则表达式用于拆分数字和字符串

时间:2017-10-10 12:11:39

标签: c# regex

寻找正则表达式引入一个空格,其中数字和字符串在用户输入中连接,除了序数指示符,例如1日,11日,22日,33日,44日等。

所以这个字符串:

  

嗨这是18dec到21世纪可用的

的形式返回
  

嗨,这是18月12日至21日期间可用的

使用此表达式

<script>

console.log(formatTime(Date()));

// https://developers.google.com/maps/documentation/javascript/geolocation
var map; var marker;
var lat = 65.025984; var lng = 25.470794; // default map location in case no position response is available
var res_data; var res_longitude; var res_latitude; var res_speed; var res_time; // res = response (data from the ajax call)
var xhr = new XMLHttpRequest();

function getPosition() {
    pos = {
        lat: res_latitude,
        lng: res_longitude,
    };
    return ( isNaN(pos.lat) || isNaN(pos.lng) ) ? false : pos; // return pos only if lat and lng values are numbers
}

function initMap() {
    // set new map, assign default properties
    map = new google.maps.Map(document.getElementById('map'), {
        center: { lat, lng }, zoom: 14
    });
    // check if the requested data is usable (lat, lng === numbers) before trying to use it
    if(getPosition() !== false) {
        map.setCenter( getPosition() ); // set latest position as the map center
        addMarker();
        console.log("InitMap ran here");
    }
}

// place marker on the map
function addMarker() {
    //console.log("Add Marker ran");
    //https://developers.google.com/maps/documentation/javascript/markers
    if(marker){ marker.setMap(null); } // remove visibility of current marker
    marker = new google.maps.Marker({
        position: getPosition(),
        map: map,
        title: formatTime(res_time),
    });
    marker.setMap(map); // set the marker 
}

function getData() {
    xhr.addEventListener("load", reqListener);
    xhr.open("GET", "http://example.com/data.txt");
    xhr.send();
}

function reqListener() {
    // res_data = long, lat, accuracy, speed, time
    //console.log("reqListener: " + xhr.responseText);
    res_data = '[' + xhr.responseText + ']';
    res_data = JSON.parse(res_data);
    res_latitude = res_data[0]; res_longitude = res_data[1]; res_accuracy = res_data[2]; res_speed = res_data[3]; res_time = res_data[4];
    var formatted_time = formatTime(res_time);

    document.getElementById('info').innerHTML = '<span class="info">Lat: ' + res_latitude + '</span><span class="info">Long: ' + res_longitude + '</span><span class="info">Accuracy: ' + res_accuracy + '</span><span class="info">Speed: ' + res_speed + '</span><span class="info">' + formatted_time + '</span>';

    addMarker();
}

function formatTime(time) {
    var t = new Date(time);
    var hours, mins, secs;
    if(t.getHours() < 10) { hours = "0" + t.getHours(); } else { hours = t.getHours(); }
    if(t.getMinutes() < 10) { mins = "0" + t.getMinutes(); } else { mins = t.getMinutes(); }
    if(t.getSeconds() < 10) { secs = "0" + t.getSeconds(); } else { secs = t.getSeconds(); }
    var hms = hours +':'+ mins +':'+ secs;
    return 'Updated: ' + hms;
}

function init() {
    getData();
    setInterval(getData, 5000); 
}

init();

</script>

<script defer 
    src="https://maps.googleapis.com/maps/api/js?key=API_KEY_REMOVED&callback=initMap">
</script>

给出

  

嗨这是18月12日到21日之前可用的

编辑:

根据@juharr dec12th的评论应该改为12月12日

1 个答案:

答案 0 :(得分:3)

您可以使用以下解决方案:

var s = "Hi is this available 18dec to 21st dec 2nd dec 1st jan dec12th";
var res = Regex.Replace(s, @"(\p{L})?(\d+)(st|[nr]d|th|(\p{L}+))", repl);
Console.WriteLine(res);
// => Hi is this available 18 dec to 21st dec 2nd dec 1st jan dec 12th

// This is the callback method that does all the work
public static string repl(Match m) 
{
    var res = new StringBuilder();
    res.Append(m.Groups[1].Value);  // Add what was matched in Group 1
    if (m.Groups[1].Success)        // If it matched at all...
        res.Append(" ");            // Append a space to separate word from number
    res.Append(m.Groups[2].Value);  // Add Group 2 value (number)
    if (m.Groups[4].Success)        // If there is a word (not st/th/rd/nd suffix)...
        res.Append(" ");            // Add a space to separate the number from the word
    res.Append(m.Groups[3]);         // Add what was captured in Group 3
    return res.ToString();
}

请参阅C# demo

使用的正则表达式是

(\p{L})?(\d+)(st|[nr]d|th|(\p{L}+))

its demo online。匹配:

  • (\p{L})? - 与单个字母匹配的可选第1组
  • (\d+) - 第2组:一个或多个数字
  • (st|[nr]d|th|(\p{L}+)) - 第3组符合以下备选方案
    • st - st
    • [nr]d - ndrd
    • th - th
    • (\p{L}+) - 第4组:任何1个或多个Unicode字母

repl回调方法接受匹配对象,并使用其他逻辑根据可选组是否匹配来构建正确的替换字符串。

如果您需要不区分大小写的搜索和替换,则传递RegexOptions.IgnoreCase选项,如果您只想将ASCII数字与RegexOptions.ECMAScript匹配,则传递\d(请注意\p{L}将即使将此选项传递给正则表达式,仍会匹配任何Unicode字母。