PDA

View Full Version : Regular Expressions, help me!



Kevin Hoang
11-03-2008, 01:37 PM
Dr đang bị mắc một chút về cái này, với cái phần kiểm tra dữ kiệu có phải là số kiểu C/C++ không?

Như các bạn biết là C/C++ Styles có mấy loại kiểu dữ liệu số như sau:

decimal: 0-9, có số âm và số dương
hexadecimal: 0-F, có một kiểu
Octal: 0-7, có một kiểu
Extend_decimal: x.xE+xxx hoặc x.xE-xxx , có số âm và số dương

Dr muốn viết một cú pháp regular để kiểm tra xem số nhập vào có thực sự là kiểu C/C++ style không?

Vậy thì phải làm thế nào để có thể làm được điều này? Rất mong các bạn chỉ giúp Dr! Xin cảm ơn!

ilovecplusplus
15-03-2008, 12:43 AM
Bác admin thử đoạn code này coi (copy ra notepad, save lại với đuôi html):


<html>
<title>Find Numbers</title>
<body>
<script language="JavaScript">
<!-- Hide code from old browsers
/*
** Author: I love cxx
** Copyright (c) 2007
** Desc: VBB ext support
** Filename: jsregex.html
** Supported browsers: Firefox v2.0+; IE 6.x+
*/
var octNumberRule = /\b(\+|-)?0[0-7]+(u|L|uL|LL|uLL)?\b/gi;
var hexNumberRule = /\b(\+|-)?0x[A-F0-9]+(u|L|uL|LL|uLL)?\b/gi;
var decNumberRule = /\b(\+|-)?(\d|[1-9]\d+)(u|L|uL|LL|uLL)?\b/gi;
var fltNumberRule = /\b(\+|-)?\d*\.\d+([eE][-+]?(\d+\.\d+|\d+))?\b/gi;

var UnknownNumberExp = -1;
var DecExp = 0;
var OctExp = 1;
var HexExp = 2;
var FltExp = 3;

function isOctal (expression) {
return octNumberRule.test (expression);
}

function isHexadecimal (expression) {
return hexNumberRule.test (expression);
}

function isDecimal (expression) {
return decNumberRule.test (expression);
}

function isFloat (expression) {
return fltNumberRule.test (expression);
}

function whatNumberExpType (expression) {
if (isFloat (expression))
return FltExp;

if (isOctal (expression))
return OctExp;

if (isDecimal (expression))
return DecExp;

if (isHexadecimal (expression))
return HexExp;

return UnknownNumberExp;
}

function isNumber (expression) {
return (whatNumberExpType (expression) != UnknownNumberExp);
}

function findAndDisplayNumbersOnly () {
var enteredText = document.frmMain.txtNumber.value;
var hightlightRules = /\b(\+|-)?((\d*\.\d+([eE][-+]?(\d+\.\d+|\d+))?)|(((0[0-7]+)|(\d|[1-9]\d+)|(0x[0-9A-F]+))(u|L|uL|LL|uLL)?))\b/gi;
var results = enteredText.match(hightlightRules);

if (results) {
var text = "";
for (var i = 0; i < results.length; ++i)
text += results[i] + "\n";
document.frmMain.txtResult.value = text;
} else {
document.frmMain.txtResult.value = "NOT FOUND";
}
}

function hightlightCode () {
var enteredText = document.frmMain.txtNumber.value;
var hightlightRules = /\b(\+|-)?((\d*\.\d+([eE][-+]?(\d+\.\d+|\d+))?)|(((0[0-7]+)|(\d|[1-9]\d+)|(0x[0-9A-F]+))(u|L|uL|LL|uLL)?))\b/gi;
var hightlightText = enteredText.replace (hightlightRules, "$&");
document.frmMain.txtCode.value = hightlightText;
}

-->
</script>
</body>
<form name="frmMain">
<p>Sample code:</p>
<textarea cols=50 rows=10 name="txtNumber"></textarea><br>
<input type="button" name="cmdCheck" onclick="findAndDisplayNumbersOnly ()" value="Find Now!"></input>
<input type="button" name="cmdHighlight" onclick="hightlightCode ()" value="Highlight Me!"></input>
<p>Result:</p>
<textarea cols="50" rows="10" name="txtResult"></textarea>
<textarea cols="50" rows="10" name="txtCode"></textarea>
</form>
</html>

Kevin Hoang
15-03-2008, 01:20 AM
Thử không thấy hiệu quả gì luôn, nhấn Highlight Me! mà nó cứ lỳ ra không thấy highlight. Đang nhác muốn thử luôn, lại bắt edit lại. Chán

Vừa xem cái expression của bác, cũng dễ hiểu là nếu người dùng nhập đúng thì nó không vấn đề gì, nhưng nếu nhập sai ví dụ như: 0x45DF5.698 nó vẫn trùng và sẽ hightlight cái phần 0x45DF5 ngay, thế thì không ổn lắm. Nhưng mà cái đoạn expression này có một điểm mà có thể học theo. Xin cảm ơn nhé!

Mà số hexadecimal và octal mà cũng có số âm và số dương hả bác?

ilovecplusplus
15-03-2008, 01:44 AM
Khổ quá, cái editor của VBB nó remove hết cả "\" nếu để trong tag PHP. Em fix lại rồi đấy, bác admin thử lại xem.

Vấn đề bác bảo về 0x45DF5.698, em công nhận đúng. Chính xác là nó hilight cả 0x45DF5 lẫn thằng .0698, có lẽ phải fix lại.

Còn vụ số âm & dương bác cứ thử với compiler trực tiếp là biết ngay ấy mà.

Kevin Hoang
15-03-2008, 02:10 AM
Ah thử được rồi, mà bác dùng cái tag php đó làm gì, highlight nhiều màu quá đọc cũng rối rắm lắm.

Dr mới nghiên cứu cái này, cho Dr hỏi chút là cái u|L|uL|LL|uLL có nghĩa gì vậy? Và cái /gi nó có tác dụng gì nhỉ?

Dr muốn làm cái expression thông minh hơn như sau nè:
Giả dụ mình nhập vào là ++123 thì nó chỉ highlight có 123 thôi, nhưng nếu là +123 thì nó sẽ hightlight tất.

Với các số octal và hexadecimal thì nếu có +/- ở đầu, hoặc có dấu chấm động, => không đúng dạng, không hightlight.

Đang boăn khoăn mấy cái chỗ đó.

Dr cũng viết một expression nhúng vào cái tag code nâng cao đây, có điều là nó vẫn không được như ý muốn. Nếu nhập đúng thì không sao, nhưng sai thì ... Xem ví dụ sau sẽ hiểu luôn.


-2000
09
+98756
++1256
--8975
89456
+ 545__
45--
5002(
45456((
45.9638
.2356
12.36
b123456

1.5E+415
-12.56E+
.235E+258.26
.23e+96

0x178
0x45CD
0xA98
0X78956CD5
0X78A9
0X789A
x1524
00x1255
0xx456879
-0x456879
0xx78945623
0x78945.456
0x4562
0x789A5.456
0x78945.A56
0x45CD5
+0x45CD5
0x45CD
--0x4526
--78CD
++0x78956
--0x456CD
800x
8x000
80x89373 + 5678
000x78800
8080x4859

ilovecplusplus
19-03-2008, 03:47 AM
Mấy cái u, uL... gì đó đơn giản thôi mà bác. Mấy cái này là suffix cho exp kiểu số nguyên (u -> unsigned, uL -> unsigned long, LL: long long (số nguyên 64bit)... (Vd: 0xffffffffLL) , chưa kể cái suffix "f" của số thực em quên chưa add vào (Vd: 0.123f)

Cái flag g (trong /gi) có nghĩa là "match all", cụ thể nếu đoạn text là "20, 30, 40" mà không có g thì nó chỉ highlight đc thằng đầu tiên (20) rồi stop.

Flag i là "case-insensitive" (không phân biệt chữ hoa /thường)


Với các số octal và hexadecimal thì nếu có +/- ở đầu...

octal/hex có +/- ở đầu là valid bác ah. Chỉ là các cách khác nhau để biểu diễn một số nguyên (try: cout << -0x0000 << endl;).

Kevin Hoang
19-03-2008, 10:06 PM
Ờ, thì cũng đoán là cái u, uL là như vậy. Nhưng mà chưa chắc chắn nên hỏi. :D

Bữa trước nghĩ nhầm, Dr hiểu rồi, cảm ơn cậu nhiều nhé. Cậu cũng rành javascript nhỉ? Cậu có thể giúp tớ viết cái hàm copy text của môọ tag nào đó theo id không? Có thể sử dụng trên FF? Cảm ơn trước nhé!

Kevin Hoang
23-03-2008, 03:04 AM
Hôm nay vừa bị sốt, thành ra lại có thời gian mò mẫn, biểu thức lằng nhằng, dễ nhầm quá. Xem lại bài viết này thấy bác ilovecplusplus nhầm thì phải:


Dòng này: var fltNumberRule = /\b(\+|-)?\d*\.\d+([eE][-+]?(\d+\.\d+|\d+))?\b/gi;
Thay bằng: var fltNumberRule = /\b(\+|-)?\d*\.\d+([e][-+]?(\d+))?\b/gi;

--------------------
Vừa làm lại cái regular expression cho cái tag code nâng cao, nhưng vẫn còn một vài chỗ chưa được. Rất mong các bác chỉ giúp Dr với!


1.5E+688.188 // Sau E+ nó là số nguyên dương chứ?
0x789A5.456 // Chỗ này nữa
0x78945.A56