Thứ Năm, 24 tháng 12, 2015

Import a large sql dump file to a MySQL database from Terminal


Today I had to import a very large SQL dump file (16 Gb) to a MySQL database using osx terminal. If you are using linux or window command line it is the same. The process is the following:
  1. Open a terminal (or shell in Linux or command prompt in window with administrative) privilleges
  2. If you are in Windows set character set to unicode. Linux is using UTF-8 by default.
    chcp 65001
  3. Connect to a mysql instance using command line
    $PATH_TO_MYSQL/mysql -h 192.168.1.1 --port=3306 -u root -p
    if you are in localhost you do not need host and port
    $PATH_TO_MYSQL/mysql -u root -p
  4. You are now in mysql shell. Set network buffer length to a large byte number. The default value may throw errors for such large data files
    set global net_buffer_length=1000000;
  5. Set maximum allowed packet size to a large byte number.The default value may throw errors for such large data files.
    set global max_allowed_packet=1000000000;
  6. Disable foreign key checking to avoid delays,errors and unwanted behaviour
    SET foreign_key_checks = 0;
    SET UNIQUE_CHECKS = 0;
    SET AUTOCOMMIT = 0;
    
  7. Import your sql dump file
    source /Users/madman/Web/dbdump151225.sql
You are done! Remember to enable foreign key checks when procedure is complete!
SET foreign_key_checks = 1;
SET UNIQUE_CHECKS = 1;
SET AUTOCOMMIT = 1;
If you are in Linux you can create a Bash script which will do the dirty job and write to stdout start and end time of import:
#!/bin/sh 
# store start date to a variable
imeron=`date`
echo "Import starting..."
dumpfile="/Users/madman/Webs/mobigate.sql" 
ddl="set names utf8; "
ddl="$ddl set global net_buffer_length=1000000;"
ddl="$ddl set global max_allowed_packet=1000000000; "
ddl="$ddl SET foreign_key_checks = 0; "
ddl="$ddl SET UNIQUE_CHECKS = 0; "
ddl="$ddl SET AUTOCOMMIT = 0; "
# if your dump file does not create a database, select one
ddl="$ddl USE mobigate; "
ddl="$ddl source $dumpfile; "
ddl="$ddl SET foreign_key_checks = 1; "
ddl="$ddl SET UNIQUE_CHECKS = 1; "
ddl="$ddl SET AUTOCOMMIT = 1; "
ddl="$ddl COMMIT ; "
time mysql -h 127.0.0.1 -u root -psa -e "$ddl" 
# store end date to a variable
imeron2=`date`
echo "End import:$imeron2"

Thứ Năm, 25 tháng 6, 2015

Will my Android App still run with ART instead of Dalvik?

With Android L, the virtual machine compiler will move to ART (Android RunTime) and only ART for 64 bit. So what do we know about ART vs Dalvik and what does it mean for App code?
ART is an  AOT (ahead of time) compiler meaning that dex2oat runs once, during the initial installation of the app. Dalvik was a JIT (just in time) compiler that ran only as the app was called.  In trade for a longer app installation time, ART frees up the processor later when the app is called.  Additionally a new garbage collector and memory allocators will reduce the number and duration of pauses meaning ART provides better responsiveness and less power draw.  But remember, the smaller memory footprint at runtime also means increased storage needs for the compiled binaries.   ART will work with ARM, x86, and MIPS hardware and show definite improvement running floating point calculations. 
So what changes to coding? Well, the good news is that ART is backward compatible, using the Dex (Dalvik executable) byte code format. So most apps should just run (and even run better). 
However, there are some things to be checked and optimizations that may be available:
  1. Check for ART by the value returned from  System.getProperty("java.vm.version"). ART is "2.0.0" or higher.
  2. If you use JNI to run C/C++ code, be sure to use CheckJNI (set debuggable="true" in the manifest).  See Debugging Android JNI with CheckJNI  (Note: this setting is for prerelease debugging and should not be set to true in the released code). 
  3. Get the latest versions of tools. ART does tighter bytecode verification at install time than Dalvik did. Code produced by the Android build tools should work but some post-processing tools (especially obfuscation tools) may produce invalid files (ok in Dalvik but rejected by ART.)
  4. Consider whether to remove some of the exception checks (which should no longer be needed since ART sees the whole code at once, but remembering that Dalvik will be around for some time.) 
  5. Remove most System.gc() calls, especially those for reducing GC_FOR_ALLOC-type occurrences or fragmentation.
  6. Don't save pointers to object instance data and don't pass a modified pointer to Release...ArrayElements()   The compacting garbage collector (already in AOSP) may move objects into memory and Get and Release calls to ArrayElements() could corrupt memory. If you make any changes to the returned array elements, you must call the appropriate function: 
    • No changes made to array > use JNI_ABORT mode, (release memory, no copy back).
    • Change(s) made, but don't need to reference them > use code 0 ( updates the array object and frees the copy).
    • Changes made and Need to commit  them >  use JNI_COMMIT (which updates the underlying array object and retains the copy).
  7. Don't attempt to look at the fields of  Object, since it now has private fields. When iterating up a class hierarchy as part of a serialization framework, stop when Class.getSuperclass()==java.lang.Object.class (don't continue until null is returned.) 
  8. Use the additional error handling  and logging in ART
    • Improved throwing and logging of NoSuchMethodError: from GetMethodID() and GetStaticMethodID()  and from
      RegisterNatives call  (caused pehaps because the method was removed by a tool such as ProGuard)
    • A  NoSuchFieldError (instead of null) from  GetFieldID() and GetStaticFieldID() 
    • A warning when subclasses try to override package-private methods.To override a class's method, declare the method as public or protected.
    • Other problems that are flagged by the ART verifier include:
      • invalid control flow
      • unbalanced moniterenter/monitorexit
      • 0-length parameter type list size
  9. Pay attention to the stricter JNI spec enforcement including that CallNonvirtual---Method() methods require the method to declare a class, not a subclass.  
  10. Watch the size of the ART unified Thread stack which should be about equal to the two Dalvik stacks (by default a 32 KB Java stack and a 1 MB native stack). Anywhere that the stack size is explicitly set needs to be checked - including Java calls to the Thread constructor including a size increase if StackOverflowError occurs.
  11. Watch pthread size (pthreat_attr_setstack() and pthreat_attr_setstacksize()as calls including AttachCurrentThread() will throw an error.
  12. Remove any dependencies on the installed .odex file format in /system/framework/data/dalvik-cache, or in DexClassLoader’s optimized output directory. While ART tries to follow the same naming and locking rules in ELF, apps should not depend on the file format. 
  13. Use the latest Mockito to correctly have Proxy InvocationHandler.invoke() receive null (instead of an empty array), if there are no arguments.
  14. Check any notifications you send. There's a new color scheme in Android L.
    • Use android.app.Norification.Builder.setColor() to set an accent color in a circle behind your icon image.
    • Remember to only use alpha only channels for the main notification icon and action icons
    • Check Heads up notifications (Those using fullScreenIntent, or high priority notifications with ringtone/vibrations)
References:
https://developer.android.com/preview/api-overview.html                                                                   

Thứ Hai, 22 tháng 6, 2015

Build FFMPEG in OSX


1.
Installing Autoconf, Automake, Libtool, Wget, Yasm:

 --- AutoConf --- 
curl -OL http://ftpmirror.gnu.org/autoconf/autoconf-2.69.tar.gz 
tar -xzf autoconf-2.69.tar.gz  
cd autoconf-2.69 
./configure && make && sudo make install 
 --- Automake ---
curl -OL http://ftpmirror.gnu.org/automake/automake-1.14.tar.gz 
tar -xzf automake-1.14.tar.gz 
cd automake-1.14 
./configure && make && sudo make install 
 --- LIBTOOL ---
curl -OL http://ftpmirror.gnu.org/libtool/libtool-2.4.2.tar.gz 
tar -xzf libtool-2.4.2.tar.gz 
cd libtool-2.4.2 
./configure && make && sudo make install
 --- WGET ---
 curl -O http://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz  
tar -xzf wget-1.15.tar.gz  
cd wget-1.15
./configure --with-ssl=openssl && make && sudo make install
 --- YASM ---
curl -OL http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz 
tar xvzf yasm-1.2.0.tar.gz 
cd yasm-1.2.0 
./configure && make -j 4 && sudo make install
--- PKG-CONFIG && ANT ----

Install Macport before, link here: http://www.macports.org/install.php

+ PKG-CONFIG:
sudo port install pkgconfig 
export PATH=$PATH:/opt/local/bin

+ANT:
sudo port install apache-ant

--- Update NASM ---
Download Nasm 2.10.05 for mac here: http://www.nasm.us/pub/nasm/releasebuilds/2.10.05/macosx/
From where I downloaded the file
nasm-2.10.05-macosx.zip
Unzipping this file resulted in a directory named nasm-2.10.05 being created.

check current version: 
$ nasm -v
NASM version 0.98.40 (Apple Computer, Inc. build 11) compiled on Aug 4 2012

move to nasm-2.10.05 folder:
check version:
./nasm -v
NASM version 2.10.05 compiled on Sep 9 2012
I decided to put the downloaded nasm in a directory called prog/nasm inside my home directory. I moved it there using

mkdir -p ~/prog/nasm
mv * ~/prog/nasm
I then added the following changes

export PATH=~/prog/nasm:$PATH
to my setup script, where I also set up other environment variables. After having rerun the setup script I could use the downloaded nasm, after first having verified that it was found using

$ nasm -v
NASM version 2.10.05 compiled on Sep 9 2012
--- END ---

Thứ Năm, 4 tháng 6, 2015

Java Regex

1-       Biểu thức chính quy (Regular expression)

1.1-   Tổng quan

Một biểu thức chính quy (Regular expressions) định nghĩa một khuôn mẫu (pattern) tìm kiếm chuỗi. Nó có thể được sử dụng tìm kiếm, sửa đổi, và thao tác trên văn bản. Khuôn mẫu được định nghĩa bởi biểu thức chính quy có thể khớp một hoặc một vài lần, hoặc không khớp với một văn bản cho trước.

Viết tắt của biểu thức chính quy là regex

1.2- Hỗ trợ các ngôn ngữ

Biểu thức chính quy (Regular expression) được hỗ trợ bởi hầu hết các ngôn ngữ lập trình, ví dụ, Java, Perl, Groovy, vv Thật không may mỗi ngôn ngữ hỗ trợ biểu thức thông thường hơi khác nhau.

2- Quy tắc viết biểu thức chính quy

No
Regular Expression
Mô tả

1
.
Khớp (match) với bất kỳ ký tự nào

2
^regex
Biểu thức chính quy phải  khớp tại điểm bắt đầu

3
regex$
Biểu thức chính quy phải khớp ở cuối dòng.

4
[abc]
Thiết lập định nghĩa, có thể khớp với a hoặc b hoặc c.

5
[abc][vz]
Thiết lập định nghĩa, có thể khớp với a hoặc b hoặc c theo sau là v hay z.

6
[^abc]
Khi dấu ^ xuất hiện như là nhân vật đầu tiên trong dấu ngoặc vuông, nó phủ nhận mô hình. Điều này có thể khớp với bất kỳ ký tự nào ngoại trừ a hoặc b hoặc c.

7
[a-d1-7]
Phạm vi: phù hợp với một chuỗi giữa a và điểm d và con số từ 1 đến 7.

8
X|Z
Tìm X hoặc Z.

9
XZ
Tìm X và theo sau là Z.

10
$
Kiểm tra kết thúc dòng.


11
\d
Số bất kỳ, viết ngắn gọn cho [0-9]

12
\D
Ký tự không phải là số, viết ngắn gon cho [^0-9]

13
\s
Ký tự khoảng trắng, viết ngắn gọn cho [ \t\n\x0b\r\f]

14
\S
Ký tự không phải khoản trắng, viết ngắn gọn cho [^\s]

15
\w
Ký tự chữ, viết ngắn gọn cho [a-zA-Z_0-9]

16
\W
Ký tự không phải chữ, viết ngắn gọn cho [^\w]

17
\S+
Một số ký tự không phải khoảng trắng (Một hoặc nhiều)

18
\b
Ký tự thuộc a-z hoặc A-Z hoặc 0-9 hoặc _, viết ngắn gọn cho [a-zA-Z0-9_].


19
*
Xuất hiện 0 hoặc nhiều lần, viết ngắn gọn cho {0,}

20
+
Xuất hiện 1 hoặc nhiều lần, viết ngắn gọn cho {1,}

21
?
Xuất hiện 0 hoặc 1 lần, ? viết ngắn gọn cho {0,1}.

22
{X}
Xuất hiện X lần, {}

23
{X,Y}
Xuất hiện trong khoảng X tới Y lần.

24
*?
* có nghĩa là xuất hiện 0 hoặc nhiều lần, thêm ? phía sau nghĩa là tìm kiếm khớp nhỏ nhất.


3- Các ký tự đặc biệt trong Java Regex (Special characters)
Một số ký tự đặc biệt trong Java Regex:
\.[{(*+?^$|
Những ký tự liệt kê ở trên là các ký tự đặc biệt. Trong Java Regex bạn muốn nó hiểu các ký tự đó theo cách thông thường bạn cần thêm dấu \ ở phía trước.

Chẳng hạn ký tự chấm . java regex đang hiểu là một ký tự bất kỳ, nếu bạn muốn nó hiểu là một ký tự chấm thông thường, cần phải có dấu \ phía trước.

// Mẫu regex mô tả một ký tự bất kỳ.
String regex = ".";
// Mẫu regex mô tả  ký tự dấu chấm.
String regex = "\\.";
4- Sử dụng String.matches(String)

   Class String

..
// Kiểm tra đối tượng toàn bộ String có khớp với regex hay không.
public boolean matches(String regex)
..
Sử dụng  method String.matches(String regex) cho phép bạn kiểm tra toàn bộ String có khớp với regex không. Đây là một cách thông dụng nhất. Hãy xem các ví dụ:

   StringMatches.java

package com.madman.tutorial.regex.stringmatches;
public class StringMatches {
 public static void main(String[] args) {
     String s1 = "a";
     System.out.println("s1=" + s1);
     // Kiểm tra toàn bộ s1
     // Khớp với bất kỳ ký tự nào
     // Quy tắc: .
     // ==> true
     boolean match = s1.matches(".");
     System.out.println("-Match . " + match);
     s1 = "abc";
     System.out.println("s1=" + s1);
     // Kiểm tra toàn bộ s1
     // Khớp với bất kỳ ký tự nào.
     // ==> false  (Rõ ràng, chuỗi 3 ký tự sao khớp với 1 ký tự bất kỳ?)
     match = s1.matches(".");
     System.out.println("-Match . " + match);
     // Kiểm tra toàn bộ s1
     // Khớp với bất kỳ ký tự nào 0 hoặc nhiều lần
     // Kết hợp các quy tắc: . và *
     // ==> true
     match = s1.matches(".*");
     System.out.println("-Match .* " + match);
     String s2 = "m";
     System.out.println("s2=" + s2);
     // Kiểm tra toàn bộ s2
     // Bắt đầu bởi m
     // Quy tắc ^
     // true
     match = s2.matches("^m");
     System.out.println("-Match ^m " + match);
     s2 = "mnp";
     System.out.println("s2=" + s2);
     // Kiểm tra toàn bộ s2
     // Bắt đầu bởi m
     // Quy tắc ^
     // ==> false  (Rõ ràng, chuỗi 3 ký tự sao khớp với 1 ký tự bất kỳ bắt đầu bởi m)
     match = s2.matches("^m");
     System.out.println("-Match ^m " + match);
     // Bắt đầu bởi m
     // Sau đó là ký tự bất kỳ, xuất hiện 1 hoặc nhiều lần.
     // Quy tắc ^ và . và +
     // true
     match = s2.matches("^m.+");
     System.out.println("-Match ^m.+ " + match);
     String s3 = "p";
     System.out.println("s3=" + s3);
     // Kiểm tra s3 kết thúc bằng p
     // Quy tắc $
     // true
     match = s3.matches("p$");
     System.out.println("-Match p$ " + match);
     s3 = "2nnp";
     System.out.println("s3=" + s3);
     // Kiểm tra toàn bộ s3
     // Kết thúc bằng p
     // ==> false  (Rõ ràng, chuỗi 4 ký tự sao khớp với 1 ký tự p cuối cùng)
     match = s3.matches("p$");
     System.out.println("-Match p$ " + match);
     // Kiểm tra toàn bộ s3
     // Ký tự bất kỳ xuất hiện 1 lần: .
     // tiếp theo là n, xuất hiện 1 hoặc tối đa 3 lần.
     // Kết thúc bởi p: p$
     // Kết hợp các quy tắc: . , {X,Y}, $
     // true
     match = s3.matches(".n{1,3}p$");
     System.out.println("-Match .n{1,3}p$ " + match);
     String s4 = "2ybcd";
     System.out.println("s4=" + s4);
     // Bắt đầu là 2
     // Tiếp theo x hoặc y hoặc z
     // Tiếp theo bất kỳ 1 hoặc nhiểu lần.
     // Kết hợp các quy tắc: [abc] , . , +
     // true
     match = s4.matches("2[xyz].+");
     System.out.println("-Match 2[xyz].+ " + match);
     String s5 = "2bkbv";
     // Bắt đầu là bất kỳ, 1 hoặc nhiểu lần
     // Tiếp theo a hoặc b, hoặc c: [abc]
     // Tiếp theo z hoặc v: [zv]
     // Tiếp theo bất kỳ
     // true
     match = s5.matches(".+[abc][zv].*");
     System.out.println("-Match .+[abc][zv].* " + match);
 }
}
Kết quả chạy ví dụ:



   SplitWithRegex.java

package com.madman.tutorial.regex.stringmatches;

public class SplitWithRegex {

   public static final String TEXT = "This is my text";

   public static void main(String[] args) {
       System.out.println("TEXT=" + TEXT);
       // Khoảng trắng xuất hiện 1 hoặc nhiều lần.
       // Các ký tự khoảng trắng: \t\n\x0b\r\f
       // Kết hợp quy tắc: \s và +
       String regex = "\\s+";
       String[] splitString = TEXT.split(regex);
       // 4
       System.out.println(splitString.length);

       for (String string : splitString) {
           System.out.println(string);
       }
    
       // Thay thế tất cả các khoảng trắng với ký tự tab.
       String newText = TEXT.replaceAll("\\s+", "\t");
       System.out.println("New text=" + newText);
   }
}

Kết quả chạy ví dụ:



EitherOrCheck.java

package com.madman.tutorial.regex.stringmatches;

public class EitherOrCheck {

   public static void main(String[] args) {

       String s = "The film Tom and Jerry!";
       // Kiểm tra toàn bộ s
       // Bắt đầu bởi ký tự bất kỳ xuất hiện 0 hoặc nhiều lần
       // Tiếp theo là từ Tom hoặc Jerry
       // Kết thúc bởi ký tự bất kỳ xuất hiện 0 hoặc nhiều lần
       // Kết hợp các quy tắc: ., *, X|Z
       // true
       boolean match = s.matches(".*(Tom|Jerry).*");
       System.out.println("s=" + s);
       System.out.println("-Match .*(Tom|Jerry).* " + match);

       s = "The cat";
       // false
       match = s.matches(".*(Tom|Jerry).*");
       System.out.println("s=" + s);
       System.out.println("-Match .*(Tom|Jerry).* " + match);

       s = "The Tom cat";
       // true
       match = s.matches(".*(Tom|Jerry).*");
       System.out.println("s=" + s);
       System.out.println("-Match .*(Tom|Jerry).* " + match);
   }

}

Kết quả chạy ví dụ:








5- Sử dụng Pattern và Matcher
1. Pattern là một đối tượng mẫu, một phiên bản biên dịch của biểu thức chính quy. Nó không có cấu tử public, và chúng ta sẽ sử dụng method tĩnh compile(String) để tạo đối tượng, với tham số là biểu thức chính quy.

2. Matcher là một phương tiện để khớp với String dữ liệu vào với đối tượng Pattern đã tạo trước đó. Class này không có cấu tử public, và chúng ta lấy đối tượng này thông qua method matcher(String) của đối tượng pattern. Với tham số String là văn bản cần kiểm tra.

3. PatternSyntaxException sẽ bị ném ra nếu biểu thức chính quy có ngữ pháp không chính xác.

String regex= ".xx.";
// Tạo đối tượng Pattern thông qua method tĩnh.
Pattern pattern = Pattern.compile(regex);
// Lấy ra đối tượng Matcher
Matcher matcher = pattern.matcher("MxxY");

boolean match = matcher.matches();

System.out.println("Match "+ match);

   Class Pattern:

public static Pattern compile(String regex, int flags) ;

public static Pattern compile(String regex);

public Matcher matcher(CharSequence input);

public static boolean matches(String regex, CharSequence input);

   Class Matcher:

public int start()

public int start(int group)

public int end()

public int end(int group)

public String group()

public String group(int group)

public String group(String name)

public int groupCount()

public boolean matches()

public boolean lookingAt()

public boolean find()

Đây là một ví dụ sử dụng Matcher và method find() để tìm kiếm các chuỗi con khớp với biểu thức chính quy.



   MatcherFind.java
package com.madman.tutorial.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MatcherFind {

   public static void main(String[] args) {

       final String TEXT = "This \t is a \t\t\t String";

       // Khoảng trắng xuất hiện 1 hoặc nhiều lần.
       String regex = "\\s+";

       Pattern pattern = Pattern.compile(regex);

       Matcher matcher = pattern.matcher(TEXT);

       int i = 0;
       while (matcher.find()) {
           System.out.print("start" + i + " = " + matcher.start());
           System.out.print(" end" + i + " = " + matcher.end());
           System.out.println(" group" + i + " = " + matcher.group());
           i++;
       }

   }
}

Kết quả chạy ví dụ:





Method Matcher.lookingAt()
   MatcherLookingAt.java

package com.madman.tutorial.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MatcherLookingAt {

   public static void main(String[] args) {
       String country1 = "iran";
       String country2 = "Iraq";

       // Bắt đầu bởi I tiếp theo là ký tự bất kỳ.
       // Tiếp theo là ký tự a hoặc e.
       String regex = "^I.[ae]";

       Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

       Matcher matcher = pattern.matcher(country1);

       // lookingAt() tìm kiếm khớp phần đầu.
       System.out.println("lookingAt = " + matcher.lookingAt());
       // Trong khi matches() phải khớp toàn bộ
       System.out.println("matches = " + matcher.matches());

       // Reset matcher với text mới, country2
       matcher.reset(country2);

       System.out.println("lookingAt = " + matcher.lookingAt());
       System.out.println("matches = " + matcher.matches());
   }
}

6- Nhóm (Group)

Một biểu thức chính quy bạn có thể tách ra thành các nhóm (group):

// Một biểu thức chính quy
String regex = "\\s+=\\d+";

// Viết dưới dạng group, bởi dấu ()
String regex2 = "(\\s+)(=)(\\d+)";

// Một cách khác.
String regex3 = "(\\s+)(=\\d+)";

Các group có thể lồng nhau, và như vậy cần một quy tắc đánh chỉ số các group.  Toàn bộ pattern được định nghĩa là group số 0. Còn lại được mô tả giống hình minh họa dưới đây:



Chú ý: Sử dụng (?:pattern) để thông báo với Java không xem đây là một group (None-capturing group)
Từ Java 7, bạn có thể xác định một group có tên (?<name>pattern), Và bạn có thể truy cập các nội dung khớp với Matcher.group (String name). Điều này làm Regex dài hơn, nhưng mã này là có ý nghĩa hơn, dễ hơn.

Nhóm bắt theo tên cũng có thể được truy cập thông qua Matcher.group (int group) với các đề án đánh số tương tự.

Nội bộ, Java chỉ lập bản đồ từ tên đến số nhóm. Do đó, bạn không thể sử dụng cùng tên để bắt 2 nhóm khác nhau.

Hãy xem một ví dụ sử dụng đánh tên cho nhóm (group) (Java >=7)

   NamedGroup.java

package com.madman.tutorial.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NamedGroup {

   public static void main(String[] args) {

    
       final String TEXT = " int a = 100;float b= 130;float c= 110 ; ";

       // Sử dụng (?<groupName>pattern) để định nghĩa một Group có tên: groupName
       // Định nghĩa group có tên declare: sử dụng (?<declare> ...)
       // Và một group có tên value: sử dụng: (?<value> ..)
       String regex = "(?<declare>\\s*(int|float)\\s+[a-z]\\s*)=(?<value>\\s*\\d+\\s*);";

       Pattern pattern = Pattern.compile(regex);

       Matcher matcher = pattern.matcher(TEXT);

       while (matcher.find()) {
           String group = matcher.group();
           System.out.println(group);
           System.out.println("declare: " + matcher.group("declare"));
           System.out.println("value: " + matcher.group("value"));
           System.out.println("------------------------------");
       }
   }
}

Kết quả chạy ví dụ:



Để dễ hiểu bạn có thể xem hình minh họa dưới đây:



7- Sử dụng Pattern, Matcher, Group và *?

Trong một số tình huống *? rất quan trọng, hãy xem một ví dụ sau:

// Đây là một regex
// Bắt gặp ký tự bất kỳ 0 hoặc nhiều lần,
// sau đó tới ký tự ' và tiếp theo là >
String regex = ".*'>";

// Đoạn TEXT1 sau đây có vẻ hợp với regex nói trên.
String TEXT1 = "FILE1'>";

// Đoạn TEXT2 sau cũng hợp với regex nói trên.
String TEXT2 = "FILE1'> <a href='http://HOST/file/FILE2'>";



*? sẽ tìm ra một phù hợp nhỏ nhất. Chúng ta xem ví dụ sau:
   NamedGroup2.java

package com.madman.tutorial.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NamedGroup2 {

  public static void main(String[] args) {
      String TEXT = "<a href='http://HOST/file/FILE1'>File 1</a>"
              + "<a href='http://HOST/file/FILE2'>File 2</a>";

      // Java >= 7.
      // Định nghĩa một group có tên fileName
      // *? ==> Nó sẽ tìm một phù hợp nhỏ nhất.
      String regex = "/file/(?<fileName>.*?)'>";

      Pattern pattern = Pattern.compile(regex);
      Matcher matcher = pattern.matcher(TEXT);

      while (matcher.find()) {
          System.out.println("File Name = " + matcher.group("fileName"));
      }
  }

}

Kết quả chạy ví dụ: